1. 程式人生 > >436. Find Right Interval

436. Find Right Interval

Given a set of intervals, for each of the interval i, check if there exists an interval j whose start point is bigger than or equal to the end point of the interval i, which can be called that j is on the "right" of i.

For any interval i, you need to store the minimum interval j's index, which means that the interval j has the minimum start point to build the "right" relationship for interval i. If the interval j doesn't exist, store -1 for the interval i. Finally, you need output the stored value of each interval as an array.

Note:

  1. You may assume the interval's end point is always bigger than its start point.
  2. You may assume none of these intervals have the same start point.

Example 1:

Input: [ [1,2] ]

Output: [-1]

Explanation: There is only one interval in the collection, so it outputs -1.

Example 2:

Input: [ [3,4], [2,3], [1,2] ]

Output:
[-1, 0, 1] Explanation: There is no satisfied "right" interval for [3,4]. For [2,3], the interval [3,4] has minimum-"right" start point; For [1,2], the interval [2,3] has minimum-"right" start point.

Example 3:

Input: [ [1,4], [2,3], [3,4] ]

Output: [-1, 2, -1]

Explanation: There is no satisfied "right" interval for [1,4] and [3,4].
For [2,3], the interval [3,4] has minimum-"right" start point.

把區間按照起點為第一關鍵字,在陣列中的index為第二關鍵字排序。

排序以後尋找當前區間I的所求的“最小右區間”,“最小右區間”是沿著當前區間I在排序後陣列的位置開始向右的第一個區間X,滿足X.start>=I.end,

找到區間X之後X在未排序陣列中的index即為所求

需要使用原index和新index,因此用一個新的類IntervalUnit將區間和原index封裝一下

查詢的時候如果按順序往後查詢,最壞情況是O(N),這樣總時間複雜度為O(N^2),因為排序過,所以可以使用二分查詢來把複雜度降低為O(NlogN)

/**
 * Definition for an interval.
 * public class Interval {
 *     int start;
 *     int end;
 *     Interval() { start = 0; end = 0; }
 *     Interval(int s, int e) { start = s; end = e; }
 * }
 */
public class Solution {
    public int[] findRightInterval(Interval[] intervals)
	{
		int len=intervals.length;
		if(len<1)
			return new int[]{};
		ArrayList<IntervalUnit> arraylist=new ArrayList<>(len);
		for(int i=0;i<len;i++)
			arraylist.add(new IntervalUnit(intervals[i], i));
		
		Collections.sort(arraylist);
		
		int[] retarr=new int[len];
		
		for(int i=0;i<len;i++)
		{
			int lo=i+1;
			int hi=len-1;
			int mid=-1;
			while(lo<=hi)
			{
				mid=lo+((hi-lo)>>1);
				int cmp=arraylist.get(mid).interval.start-arraylist.get(i).interval.end;
				if(cmp==0)
					break;
				else if(cmp<0)
					lo=mid+1;
				else {
					hi=mid-1;
				}
			}
			retarr[arraylist.get(i).index]=lo<=hi?arraylist.get(mid).index:-1;
		}
		
		return retarr;
	}
}


class IntervalUnit implements Comparable<IntervalUnit>
{
	Interval interval;
	int index;
	public IntervalUnit(Interval interval,int index)
	{
		this.interval=interval;
		this.index=index;
		// TODO Auto-generated constructor stub
	}
	
	@Override
	public int compareTo(IntervalUnit o)
	{
		// TODO Auto-generated method stub
		if(interval.start!=o.interval.start)
			return interval.start-o.interval.start;
		return index-o.index;
	}
}