252,给出一堆闭区间,问这些区间是否互相都不相交

思路是对区间按照第一位排序,然后遍历排序后的区间,维护一个第二位的最小值,看是否有一个区间额第一位大于该最小值,如果有那么这两个区间肯定不相交。

public boolean isInterval(int[][] intervals){
List<Interval> pairs = new ArrayList<>();
for(int i = 0; i < intervals.length; i++){
pairs.add(new Interval(intervals[i][0], intervals[i][1]));
}
Collections.sort(pairs, new Comparator<Interval>() {
@Override
public int compare(Interval o1, Interval o2) {
Integer i1 = new Integer(o1.s);
Integer i2 = new Integer(o2.s);
return i1.compareTo(i2);
}
});
int min = pairs.get(0).e;
for(int i = 1; i < pairs.size(); i++){
if(pairs.get(i).s > min)
return false;
min = Math.min(min, pairs.get(i).e);
}
return true;
}


253,在252的基础上改进,每一个区间是会议的时间,问需要多少个会议室。思路还是延续上一题,先排序,然后遍历。还需要维护一个第二位的最小值,如果遍历的当前区间的第一位小于等于最小值,那么铁定需要加一个room,那如果大于呢?这时就不需要添加room了,因为它可以等待那一个会议结束用那个会议室,这时就要把那个最小值改为自己的第二位,这样说来,每一个区间遍历完都需要记录第二位,我们需要得到这些所有第二位的最小值,那么很自然会想到使用最小堆来实现。

public int count(int[][] intervals){
List<Interval> pairs = new ArrayList<>();
for(int i = 0; i < intervals.length; i++){
pairs.add(new Interval(intervals[i][0], intervals[i][1]));
}
Collections.sort(pairs, new Comparator<Interval>(){
@Override
public int compare(Interval o1, Interval o2) {
Integer i1 = new Integer(o1.s);
Integer i2 = new Integer(o2.s);
return i1.compareTo(i2);
}
});
int count = 1;
PriorityQueue<Integer> queue = new PriorityQueue<>();
queue.add(pairs.get(0).e);
for(int i = 1; i < pairs.size(); i++){
Interval in = pairs.get(i);
if(in.s > queue.peek())
queue.poll();
else
count++;
queue.add(in.e);
}
return count;
}


另外百度也有一道类似题目,就是给了很多的线段,然后用一个点可以清楚所有的经过这个点的线段,所有线段都在x轴上,问需要最少多少个点清楚所有的线段。

与253很类似,差别在于,这里不需要维护最小堆了,只需要维护最小值即可,每一次遇到一个不相交,这时需要就需要加一个点,然后前面的线段就可以不管了,然后把最小值更新为这个线段的第二位即可。

总之,在所有的区间问题里面,按照第一位排序是关键点。