扫描线技巧:安排会议室 :: labuladong的算法小抄 #1035
Replies: 15 comments 8 replies
-
绝了 |
Beta Was this translation helpful? Give feedback.
-
这个衍生解法确实秒 |
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.
-
会议室也可以用贪心做啊,按照结束时间排序,当前会议正在开着的时候,如果有会议来了就新建会议室 (当前会议室贪心占用,不释放),当前会议开完了,有新会议就用原会议室
|
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.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
文章链接点这里:扫描线技巧:安排会议室
评论礼仪 见这里,违者直接拉黑。
Beta Was this translation helpful? Give feedback.
All reactions