扫描线技巧:安排会议室 :: labuladong的算法小抄 #1035
Replies: 15 comments 8 replies
-
这个衍生解法确实秒 |
Beta Was this translation helpful? Give feedback.
-
为什么 i < n && j < n呢,自己写的时候循环的条件比较难想清楚 |
Beta Was this translation helpful? Give feedback.
-
太妙了,官方题解用的是最小堆 |
Beta Was this translation helpful? Give feedback.
-
关于 会议室1 和 会议室2 需要会员的问题 |
Beta Was this translation helpful? Give feedback.
-
1、begin[i]=end[j]的情况没考虑? |
Beta Was this translation helpful? Give feedback.
-
check in |
Beta Was this translation helpful? Give feedback.
-
我这有个更快的算法! var minMeetingRooms = function(intervals) {
// 原数组按开始时间升序
intervals = intervals.sort((a,b) => a[0] - b[0]);
//维护一个数组表示每个会议室的结束时间,初始值为第一个区间的结束时间
const res = [intervals[0][1]];
for (let i = 1; i < intervals.length; i ++) {
const item = intervals[i];
let min = 0, flag = false;
// 遍历已有的会议室数组,找出结束时间最早且早于当前区间开始时间的会议室
for (let j = 0; j < res.length; j ++) {
if (res[j] <= item[0] && res[j] <= res[min]) {
min = j;
flag = true;
};
}
if (flag) {
res[min] = item[1] //将找出的会议室结束时间更新
}else {
res.push(item[1]); //未找到则新增一个会议室
};
}
return res.length;
}; |
Beta Was this translation helpful? Give feedback.
-
会议室也可以用贪心做啊,按照结束时间排序,当前会议正在开着的时候,如果有会议来了就新建会议室 (当前会议室贪心占用,不释放),当前会议开完了,有新会议就用原会议室
|
Beta Was this translation helpful? Give feedback.
-
用楼提到的差分做了一下 class Solution {
int[] diff;
public int minMeetingRooms(int[][] intervals) {
int max = Integer.MIN_VALUE;
for (int i = 0; i < intervals.length; i++) {
max = Math.max(max, intervals[i][1]);
}
diff = new int[max];
for (int i = 0; i < intervals.length; i++) {
int k = intervals[i][0];
int j = intervals[i][1] - 1;
// int val = 1;
increment(k, j, 1);
}
int[] res = result(diff);
int result = 0;
for (int i = 0; i < res.length; i++) {
result = Math.max(result, res[i]);
}
return result;
}
public void increment(int i, int j, int val) {
diff[i] += val;
if (j + 1 < diff.length) {
diff[j + 1] -= val;
}
}
public int[] result(int[] df) {
int[] res = new int[df.length];
// 根据差分数组构造结果数组
res[0] = df[0];
for (int i = 1; i < df.length; i++) {
res[i] = res[i - 1] + df[i];
}
return res;
}
} |
Beta Was this translation helpful? Give feedback.
-
优先队列方法 public int minMeetingRooms(int[][] intervals) {
PriorityQueue<Integer> pq = new PriorityQueue<>();
int n = intervals.length;
Arrays.sort(intervals,Comparator.comparingInt(a->a[0]));
pq.offer(intervals[0][1]);
for(int i = 1; i < intervals.length; i++) {
if(intervals[i][0] >= pq.peek()) {
pq.poll();
}
pq.offer(intervals[i][1]);
}
return pq.size();
} |
Beta Was this translation helpful? Give feedback.
-
完全联想不到啊,东哥你是如何一步一步联想到的? |
Beta Was this translation helpful? Give feedback.
-
打卡,附上详细注解的Java代码 public class Interval {
int start, end;
Interval(int start, int end) {
this.start = start;
this.end = end;
}
}
public int minMeetingRooms(List<Interval> intervals) {
//这是一个区间调度的问题,所以我们考虑使用贪心算法
int n = intervals.size();
//记录每个会议的开始时间
int[] start = new int[n];
//记录每个会议的结束时间
int[] end = new int[n];
int temp = 0;
//通过循环将所有会议的开始时间和结束时间遍历并且赋值完
for (Interval interval : intervals) {
start[temp] = interval.start;
end[temp] = interval.end;
temp++;
}
//将开始时间和结束时间进行一个升序排列
Arrays.sort(start);
Arrays.sort(end);
//通过扫描线去扫描所有的开始和结束时间,然后如果遇到一个开始时间就让count++,
// 遇到一个结束时间就让count--,最后看还剩下几个count,剩下的count数量就是同时有几个会议在开,也就是需要的会议室数量
int count = 0;
//i和j是双指针
int i = 0, j = 0;
int res=0;
while (i < n && j < n) {
//开始的时候小于结束的时间
if(start[i]<end[j]){
count++;
i++;
}else{
//开始的时候大于等于结束的时间
count--;
j++;
}
//记录每轮的最大值
res=Math.max(res,count);
}
return res;
} |
Beta Was this translation helpful? Give feedback.
-
为啥看不到?咋开会员啊? |
Beta Was this translation helpful? Give feedback.
-
文章链接点这里:扫描线技巧:安排会议室
评论礼仪 见这里,违者直接拉黑。
Beta Was this translation helpful? Give feedback.
All reactions