在面试时被要求计算基于给定的两个数组可以举行的最大会议次数。
数组的大小为1到50,并且数组中的值最大为1到1000。
我有一个代表会议开始时间的数组-[1,3,3,5,7]。 另一个代表上述会议所需时间的数组-[2,2,1,2,1]
根据上述数据,第一次会议从1开始,持续2个小时。因此会议时间为2小时,因此从1小时到3小时不等。 第二次和第三次会议从3开始,持续2个小时或1个小时。因此他们在第二次会议上覆盖3到5,在第三次会议上覆盖3到4。 第四次聚会从5点开始,持续2小时。持续时间为2小时,因此覆盖5到7 上次会议从7点开始,持续1小时。
第二个和第三个同时发生,所以我们只需要选择一个就可以安排最大数量的会议。
对于上面给出的示例数据,我们可以安排4次会议。
另一个例子:
会议开始时间-[1,3,5]。 会议花费的时间-[2,2,2]。
这里没有会议可以冲突,因此最多可以安排3次会议。
这是我想出的代码:
public static int getMaximumMeetings(List<Integer> start, List<Integer> timeTaken) {
// Map with key as meeting start time, and value as the list of time taken values.
Map<Integer, List<Integer>> map = new LinkedHashMap<>();
for (int i = 0; i < start.size(); i++) {
List<Integer> list = map.get(start.get(i));
if (list == null) {
list = new ArrayList<>();
}
list.add(timeTaken.get(i));
map.put(start.get(i), list);
}
System.out.println(map);
// Get meetings one by one
Set<Integer> keys = map.keySet();
Iterator<Integer> it = keys.iterator();
Integer time = it.next();
List<Integer> list = map.get(time);
// Sort the time taken values so we can pick the least duration meeting
list.sort(null);
int count = 1;
while (it.hasNext()) {
List<Integer> prevList = list;
int value = prevList.get(0);
int prevTime = time;
time = it.next();
list = map.get(time);
list.sort(null);
// Check if total time taken for this meeting is less than the next meeting starting time.
if (value + prevTime <= time) {
count++;
} else {
time = prevTime;
list = prevList;
}
}
return count;
}
此程序仅清除了12个中的5个测试用例,其余所有失败。所有测试用例都是隐藏的。所以我不清楚这段代码有什么问题。
答案 0 :(得分:4)
它是经典的“间隔调度问题”。您的方法将以最短的时间参加会议。
最短的持续时间无法提供最佳输出。 示例之一可能是间隔(以开始时间为结束时间)
1-11、10-12、13-20、21-30、29-32、31-40
可以证明,最佳解决方案是首先选择最短的完成时间。
使用此算法 按完成时间对元素进行排序。 使用贪婪并包括第一个间隔。标记结束时间。
如果第二个间隔在结束时间之后开始,则也将其包括在内并更新结束时间。否则,请移至第三间隔。
继续该方法。
您将获得会议数量以及会议列表
答案 1 :(得分:1)
我可以想到您没有考虑的以下问题(尽管您的算法思想不正确,这将是主要问题):
map
并进行两个同时开始的采访时,无论时间长短,您总是会进行第一次采访。这样,如果第一次面试要花更多的时间,而第二次面试要花更多的时间。说句公道话,您可能很难读懂。
答案 2 :(得分:1)
可以使用贪婪方法解决此问题。 @Abhay已经提供了不错的explanation,而我想添加一些代码。
以下是一些基本的实现示例,并附有我的评论。主要思想来自here,其中还包括复杂性分析和正确性证明。
static int getMaximumMeetings(List<Integer> start, List<Integer> timeTaken) {
List<Interval> list = new ArrayList<>(); // create a List of Interval
for (int i = 0; i < start.size(); i++) {
list.add(new Interval(start.get(i), start.get(i) + timeTaken.get(i)));
}
list.sort(Comparator.comparingInt(i -> i.end)); // sort by finish times ascending
int res = 0;
int prevEnd = Integer.MIN_VALUE; // finish time of the previous meeting
for (Interval i : list) {
if (i.start >= prevEnd) { // is there a conflict with the previous meeting?
res++;
prevEnd = i.end; // update the previous finish time
}
}
return res;
}
仅是一些Interval
实体的示例:
class Interval {
int start;
int end;
Interval(int start, int end) {
this.start = start;
this.end = end;
}
}