The essence of interval partitioning problem is that we want to fit all the intervals into as few rooms as possible so that none of them overlap with others in the same room.

Given a list of interval , find the maximum overlaping. 

For example, if input is 0,5 2,9 8,10 6,9 then ans is 2 as 8,10 overlap in 2,9 and 6,9
Number of Airplanes in the Sky: Given an interval list which are flying and landing time of the flight. How many airplanes are on the sky at most? 

For interval list [[1,10],[2,3],[5,8],[4,7]], return 3
Note

If landing and flying happens at the same time, we consider landing should happen at first.
Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si < ei), find the minimum number of conference rooms required.

For example,
Given [[0, 30],[5, 10],[15, 20]],
return 2. 
Given a set of intervals (time in seconds) find the set of intervals that overlap. Follow-up: what if we were to find the interval with maximum overlap.

Thoughts

This question is very similar to meeting rooms 2,which is equivalent to given a interval set, find minimum rooms to hold all the intervals. Like that question, we can use the greedy algorithm to solve it. But notice that,before we do the one-pass greedy/DP algorithm, we need to sort the intervals by some order, which can be start time or finish time.

  • it seems that if we want to compare one interval with next, then we sort by start time

  • if we want to compare one with everything else, then we sort by finish time.

Never forget to sort the intervals first!!!

Code

method 1: time O(n^2) space O(1)

The good thing about this method is that we can easily adapt the algorithm to return the set of intervals that overlap, or even the set of intervals with max overlap. The bad thing is that this method runs in O(n^2) time, and if we were to return all the sets, then it loses the advantage of space O(1).

public int minMeetingRooms(Interval[] intervals) {
        //edge case
        if (intervals == null || intervals.length == 0){
            return 0;
        }
        //sort
        Arrays.sort(intervals, new Comparator<Interval>(){
            public int compare(Interval a, Interval b){
                return a.end - b.end;
            }
        });
        //greedy
        int max = 1;
        int count = 1;
        for (int i = 0; i < intervals.length; i++){
            count = 1;
            for (int j = i + 1; j < intervals.length; j++){
                if (intervals[i].end > intervals[j].start){
                    count++;
                }
            }
            max = Math.max(max, count);
        }
        return max;
    }

method 2 : time O(nlogn), space O(n)

it doesn't matter whether sort by start or by end if we choose to use heap. if two intervals [a,b] and [c,d] intersects, then

  • either b > c, if we sort by start, then we consider b > c as conditionals

  • or d > a, if we sort by end, then we consider d > a as conditionals


public int minMeetingRooms(Interval[] intervals) {
        //edge case
        if (intervals == null || intervals.length == 0){
            return 0;
        }
        //sort
        Arrays.sort(intervals, new Comparator<Interval>(){
            public int compare(Interval a, Interval b){
                return a.start - b.start;
            }
        });
        //greedy
        PriorityQueue<Integer> minHeap = new PriorityQueue<Integer>();
        int curEnd = intervals[0].end;
        minHeap.offer(curEnd);
        for (int i = 1; i < intervals.length; i++){
            Interval temp = intervals[i];
            if (minHeap.peek() > temp.start){
                minHeap.offer(temp.end);
            }else{
                minHeap.poll();
                minHeap.offer(temp.end);
            }
        }
        return minHeap.size();
    }

liut2的算法笔记
0 声望1 粉丝

引用和评论

0 条评论