为什么需要先在#34;会议室2" Leetcode?

时间:2017-07-24 22:17:41

标签: algorithm

以下是问题"会议室2"在Leetcode:

  

给定一系列由开始和结束组成的会议时间间隔   次[[s1,e1],[s2,e2],...](si      

例如,给定[[0,30],[5,10],[15,20]],返回2.

众所周知,可能的解决方案是在比较相邻会议的开始和结束时间之前对间隔数组进行排序。

    public int minMeetingRooms(Interval[] intervals) {
        Arrays.sort(intervals, new Comparator<Interval>() {
            public int compare(Interval a, Interval b) {
                return a.start - b.start;
            }
        });
        List<Interval> list = new ArrayList<>(Arrays.asList(intervals));
        int count = 0;
        while (!list.isEmpty()) {
            int end = list.remove(0).end; count++; // create new timeline
            Iterator<Interval> ite = list.iterator();
            while (ite.hasNext()) {
                Interval next = ite.next();
                if (next.start >= end) { // add to current timeline
                    end = next.end;
                    ite.remove();
                }
            }
        }
        return count;
    }

但是,让我们说我们有以下代码来检测两次会议之间的时间冲突,

    private boolean isConflict(Interval a, Interval b) {
        boolean abfb = (a.start < b.start && a.end <= b.start);
        boolean aaftb = (b.start < a.start && b.end <= a.start);
        return !(abfb || aaftb);
    }

例如,我们有间隔:[[15,20],[12,14],[1,17],[0,30],[7,10],[5,10]]。从[15,20]开始, Room#1的时间表应为:[[7,10],[12,14],[15,20]]

现在它仍然是[[1,17],[0,30],[5,10]],他们都需要一个新的房间, Room#2 : [[1,17]]Room#3 : [[0,30]]Room#4 : [[5,10]], 所以我们需要4个房间。

这是代码,

    public int minMeetingRooms(Interval[] intervals) {
        List<Interval> list = new LinkedList<>(Arrays.asList(intervals));
        int count = 0;
        while (!list.isEmpty()) {
            List<Interval> group = new ArrayList<>();
            group.add(list.remove(0)); count++;
            Iterator<Interval> ite = list.iterator();
            while (ite.hasNext()) {
                Interval noGroup = ite.next();
                boolean conflict = false;
                for (Interval inGroup : group) {
                    if (isConflict(inGroup,noGroup)) { conflict = true; break; }
                }
                if (!conflict) {
                    group.add(noGroup);
                    ite.remove();
                }
            }
        }
        return count;
    }

上述代码通过了71/77测试,但在72日失败了。如果我们不首先对间隔进行排序,任何人都能说出它为什么不起作用的原因?

2 个答案:

答案 0 :(得分:1)

对于某些输入集,您的“贪婪”算法无法充分利用房间。它接受它在间隔列表中找到的第一个拟合。相反,它需要使最接近适合每个可用的开口。实现此目的的一种方法是按开始时间对间隔进行排序;这样,一旦完成最新的会议,它总会找到最早的会议。

例如,生成几组会议,单位间隔为:3个,4个,5个和6个单位。

[[1, 3], [4, 6], [7, 9], ...]
[[1, 4], [5, 8], [9, 12], ...]
[[1, 5], [6, 10], [11, 15], ...]
[[1, 6], [7, 12], [13, 18], ...]

按顺序将它们输入您的算法,您将获得最佳的4个房间。随机随机播放,你需要5或6个房间。

答案 1 :(得分:1)

您无需对数组进行排序。它可以用O(n)时间复杂度来解决。我们的想法是创建一个count数组,并使用索引+1的{​​{1}}和索引start[i]的{​​{1}}进行更新。 -1end[i]是会议的相应开始和结束时间的数组。

之后,您只需添加所有startend并形成精确计数数组,然后返回该数组中的最大值。以下是伪代码:

+1