前言
本文将介绍会议室最大安排会议次数的算法题,使用贪心算法和暴力两种方式进行介绍。
正文
题目描述
一些会议要占用一个会议室宣讲,会议室不能同时安排两个会议。给出每一个会议开始的时间和结束的时间。如何来安排会议的日程,要求会议室安排会议的场次最多,返回最多的会议安排次数。
示例:一场演讲从1点开始到6点结束、一个讲座从7点开始导9点结束,给出每个会议要占用会议室的开始和结束时间,根据这些时间合理安排会议室,使会议室能最大程度的安排更多的会议。
思路分析
根据题目描述,我们会得到一个二维数组,二维数组里存放着每个会议的开始和结束时间,比如:[[1,3],[1,5],[2,4],[3,6]]。
每个会议不能同时占用会议室,所以要避免会议室的冲突,例如选了[1,3]这个会议就不能选[1,5]、[2,4]这两个会议了,但是可以选[3,6]。
贪心分析
使用贪心算法解决这个题目时,打开我们野马般的思绪,分析一下可能的贪心点,比如:
- 哪个会议开始的早,就优先安排哪个会议
- 优先选择会议时间短的会议
- 优先选择结束时间最早的会议
第一种贪心策略是无效的,假如给出的会议是[0,24]、[1,2]、[2,3]、[3,4],按最早的优先安排的话,只能安排一个会议了,所以这个是不正确的。
第二种贪心策略也是无效的,假如给出的会议是[0,7]、[8,14]、[6,9],按持续时间短安排的话,[6,9]时间最短,但是只能安排一个会议,所以这个策略也是无效的。
第三种贪心策略是有效的,下面对第三种策略进行分析。
假如给出的会议时间为:[1,2]、[1,5]、[2,8]、[3,6]、[3,11],分析过程如下:
- 按会议结束时间从小到大排序
- 从排序后第一个会议开始遍历统计,如果有冲突则删掉冲突的会议
- 接着开始统计下一个会议,如果有冲突则删掉冲突的会议
- 依次类推,直到遍历完,剩余的会议数就是可以安排最大的会议次数
暴力递归
使用暴力递归方式判断思路比较简单,只需要对每一个会议进行遍历,如果有冲突的就去掉,如果不冲突就计数,对每一个会议都进行与其他会议比较,最后得到最大的结果就是可安排的最大会议次数。
代码实现
贪心算法
使用贪心算法代码实现如下:
先定义一个比较器,用来对会议进行排序:
public class MettingComparator implements Comparator<int[]> {
@Override
public int compare(int[] o1, int[] o2) {
return o1[1] - o2[1];
}
}
用贪心算法进行统计会议次数:
public int bestArrange(int[][] mettings) {
Arrays.sort(mettings, new MettingComparator());
int timeLine = 0;
int result = 0;
// 依次遍历每一个会议,结束时间早的会议先遍历
for (int[] metting : mettings) {
if (timeLine <= metting[0]) {
result++;
timeLine = metting[1];
}
}
return result;
}
暴力递归
使用暴力递归方式,代码如下 :
public int bestArrange(int[][] mettings) {
if (mettings == null || mettings.length == 0) {
return 0;
}
return process(mettings, 0, 0);
}
public int process(int[][] mettings, int done, int timeLine) {
if (mettings.length == 0) {
return done;
}
int max = done;
// 枚举每一个会议
for (int i = 0; i < mettings.length; i++) {
if (mettings[i][0] >= timeLine) {
int[][] next = copy(mettings, i);
max = Math.max(max, process(next, done + 1, mettings[i][1]));
}
}
return max;
}
public int[][] copy(int[][] mettings, int i) {
int[][] ans = new int[mettings.length - 1][];
int index = 0;
for (int k = 0; k < mettings.length; k++) {
if (k != i) {
ans[index++] = mettings[k];
}
}
return ans;
}
总结
本文将介绍会议室最大安排会议次数的算法题,使用贪心算法和暴力两种方式进行介绍。其中使用贪心算法主要是要找到正确的贪心策略,而暴力递归的话是毫无道理可言,直接硬刚就可以了。