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:
- You may assume the interval's end point is always bigger than its start point.
- 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;
}
}