Facebook面試題 meeting rooms 求同時最多meeting room的時間

耀凱考前突擊大師發表於2017-01-07

給出會議開始和結束時間,求meeting room interval最多的時間點。返回任意一個時間即可。

  • 顯然本題可以方便地使用掃描線演算法解決。在掃描線段的同時儲存一個時間。最終返回最多interval對應的時間即可。整個演算法可以描述如下:
    1. 將meeting開始和結束的時間點分別存在list中。
    2. 對整個list按時間排序。相同的時間結束應該優先於開始。
    3. 遍歷排序好的list,對同時存在的線段進行計數並記錄時間。

O(nlogn)時間,O(n)空間。因為我們最多對2n個點進行了儲存,排序和遍歷。

演算法的Java實現如下:

/**
 * Definition of Interval:
 * public class Interval {
 *  int start, end;
 *  Interval(int start, int end) {
 *      this.start = start;
 *      this.end = end;
 *  }
 * }
 */


class Point {
    int time;
    int flag;

    public Point(int time, int flag) {
        this.time = time;

        //end flag = 0, start flag = 1
        this.flag = flag;
    }

    public static Comparator<Point> PointComparator = new Comparator<Point>() {
        @Override
        public int compare(Point p1, Point p2) {
            if (p1.time == p2.time) {
                return p1.flag - p2.flag; // end has priority over start
            }
            return p1.time - p2.time;
        }
    };
}

class Solution {
    public int timeWithMostIntervals(List<Interval> meetings) {
        if (meetings == null || meetings.size() == 0) {
            return 0;
        }

        List<Point> lines = new ArrayList<meetings.size() * 2>();
        for (Interval i : meetings) {
            lines.add(i.start, 1);
            lines.add(i.end, 0);
        }

        Collections.sort(lines, Point.PointComparator);

        int ret = 0;
        int max = Integer.MIN_VALUE;
        int count = 0;
        for (int i = 0; i < lines.size(); i++) {
            if (lines.get(i).flag == 0) {
                count--;
            }
            else {
                count++;
            }

            if (count > max) {
                max = count;
                ret = lines.get(i).time;
            }
        }

        return ret;
    }
}

相關文章