普通视图
震惊!三万star开源项目竟有致命Bug?
每日一题-重新安排会议得到最多空余时间 II🟡
给你一个整数 eventTime
表示一个活动的总时长,这个活动开始于 t = 0
,结束于 t = eventTime
。
同时给你两个长度为 n
的整数数组 startTime
和 endTime
。它们表示这次活动中 n
个时间 没有重叠 的会议,其中第 i
个会议的时间为 [startTime[i], endTime[i]]
。
你可以重新安排 至多 一个会议,安排的规则是将会议时间平移,且保持原来的 会议时长 ,你的目的是移动会议后 最大化 相邻两个会议之间的 最长 连续空余时间。
请你返回重新安排会议以后,可以得到的 最大 空余时间。
注意,会议 不能 安排到整个活动的时间以外,且会议之间需要保持互不重叠。
注意:重新安排会议以后,会议之间的顺序可以发生改变。
示例 1:
输入:eventTime = 5, startTime = [1,3], endTime = [2,5]
输出:2
解释:
将 [1, 2]
的会议安排到 [2, 3]
,得到空余时间 [0, 2]
。
示例 2:
输入:eventTime = 10, startTime = [0,7,9], endTime = [1,8,10]
输出:7
解释:
将 [0, 1]
的会议安排到 [8, 9]
,得到空余时间 [0, 7]
。
示例 3:
输入:eventTime = 10, startTime = [0,3,7,9], endTime = [1,4,8,10]
输出:6
解释:
将 [3, 4]
的会议安排到 [8, 9]
,得到空余时间 [1, 7]
。
示例 4:
输入:eventTime = 5, startTime = [0,1,2,3,4], endTime = [1,2,3,4,5]
输出:0
解释:
活动中的所有时间都被会议安排满了。
提示:
1 <= eventTime <= 109
n == startTime.length == endTime.length
2 <= n <= 105
0 <= startTime[i] < endTime[i] <= eventTime
-
endTime[i] <= startTime[i + 1]
其中i
在范围[0, n - 2]
之间。
搭建一款结合传统黄历功能的日历小程序
JavaScript 防抖与节流:从原理到实践的完整指南
列表分页中的快速翻页竞态问题
qiankun 路由选择不同模式如何书写不同的配置
vue3,你看setup设计详解,也是个人才
盘点字体性能优化方案
一文了解什么是Dart
一篇文章说明白web前端性能优化
可配置永久生效的Table组件的封装过程
前端内容保护:如何有效防止用户复制页面内容?
从需求到封装:手把手带你打造一个高复用、可定制的Flutter日期选择器
玩转Vue Router:这些实用组件让你的SPA如虎添翼!
深入浅出React Hooks:useEffect那些事儿
刷新页面前, 我们能够将请求发出么
重新安排会议得到最多空余时间 II
方法一:贪心
假设当前平移的会议为 $i$,那么平移的最优解有两种情况:
-
如果会议 $i$ 可以移动到某个空余时间段,且该空余时间段不是会议 $i$ 左右两侧相邻的两个空余时间段,那么平移会议 $i$ 可以得到一个新的空余时间段,时长为会议 $i$ 和其左右两侧相邻空余时间段的时长之和
-
否则,平移会议 $i$ 可以将其左右两侧相邻空间时间段进行合并
显然,重新安排会议后得到的最大空余时间必定为平移某个会议后,得到的新的空余时间段的最大值。
我们使用 $q[i]$ 记录会议 $i$ 是否适用于第一种情况,首先从左到右遍历会议,同时记录当前遍历到的会议 $i$ 左侧非相邻的空余时间段的最大时长 $t_1$,如果 $t_1 \ge \textit{endTime}[i] - \textit{startTime}[i]$,那么说明会议 $i$ 左侧有满足第一种情况的空余时间段,记 $q[i] = \text{true}$。同样地,我们从右到左遍历会议,记下会议 $i$ 右侧是否有满足第一种情况的空余时间段。
我们枚举平移的会议 $i$,同时令 $\textit{left}_i$ 表示左侧相邻会议的结束时间,$\textit{right}_i$ 表示右侧相邻会议的开始时间,然后根据 $q[i]$ 的值判断平移会议 $i$ 属于哪个情况:
-
情况一:新的空余时间段的时长为 $\textit{right}_i - \textit{left}_i$
-
情况二:新的空余时间段的时长为 $\textit{right}_i - \textit{left}_i - (\textit{endTime}[i] - \textit{startTime}[i])$
返回所有枚举结果的最大值。
###C++
class Solution {
public:
int maxFreeTime(int eventTime, vector<int>& startTime, vector<int>& endTime) {
int n = startTime.size();
vector<bool> q(n);
for (int i = 0, t1 = 0, t2 = 0; i < n; i++) {
if (endTime[i] - startTime[i] <= t1) {
q[i] = true;
}
t1 = max(t1, startTime[i] - (i == 0 ? 0 : endTime[i - 1]));
if (endTime[n - i - 1] - startTime[n - i - 1] <= t2) {
q[n - i - 1] = true;
}
t2 = max(t2, (i == 0 ? eventTime : startTime[n - i]) - endTime[n - i - 1]);
}
int res = 0;
for (int i = 0; i < n; i++) {
int left = i == 0 ? 0 : endTime[i - 1];
int right = i == n - 1 ? eventTime : startTime[i + 1];
if (q[i]) {
res = max(res, right - left);
} else {
res = max(res, right - left - (endTime[i] - startTime[i]));
}
}
return res;
}
};
###Go
func maxFreeTime(eventTime int, startTime []int, endTime []int) int {
n := len(startTime)
q := make([]bool, n)
t1, t2 := 0, 0
for i := 0; i < n; i++ {
if endTime[i] - startTime[i] <= t1 {
q[i] = true
}
if i == 0 {
t1 = max(t1, startTime[i])
} else {
t1 = max(t1, startTime[i] - endTime[i - 1])
}
if endTime[n - i - 1] - startTime[n - i - 1] <= t2 {
q[n - i - 1] = true
}
if i == 0 {
t2 = max(t2, eventTime - endTime[n - 1])
} else {
t2 = max(t2, startTime[n - i] - endTime[n - i - 1])
}
}
res := 0
for i := 0; i < n; i++ {
left := 0
if i != 0 {
left = endTime[i - 1]
}
right := eventTime
if i != n - 1 {
right = startTime[i + 1]
}
if q[i] {
res = max(res, right - left)
} else {
res = max(res, right - left - (endTime[i] - startTime[i]))
}
}
return res
}
###Python
class Solution:
def maxFreeTime(self, eventTime: int, startTime: list[int], endTime: list[int]) -> int:
n = len(startTime)
q = [False] * n
t1 = 0
t2 = 0
for i in range(n):
if endTime[i] - startTime[i] <= t1:
q[i] = True
t1 = max(t1, startTime[i] - (0 if i == 0 else endTime[i - 1]))
if endTime[n - i - 1] - startTime[n - i - 1] <= t2:
q[n - i - 1] = True
t2 = max(t2, (eventTime if i == 0 else startTime[n - i]) - endTime[n - i - 1])
res = 0
for i in range(n):
left = 0 if i == 0 else endTime[i - 1]
right = eventTime if i == n - 1 else startTime[i + 1]
if q[i]:
res = max(res, right - left)
else:
res = max(res, right - left - (endTime[i] - startTime[i]))
return res
###Java
class Solution {
public int maxFreeTime(int eventTime, int[] startTime, int[] endTime) {
int n = startTime.length;
boolean[] q = new boolean[n];
for (int i = 0, t1 = 0, t2 = 0; i < n; i++) {
if (endTime[i] - startTime[i] <= t1) {
q[i] = true;
}
t1 = Math.max(t1, startTime[i] - (i == 0 ? 0 : endTime[i - 1]));
if (endTime[n - i - 1] - startTime[n - i - 1] <= t2) {
q[n - i - 1] = true;
}
t2 = Math.max(t2, (i == 0 ? eventTime : startTime[n - i]) - endTime[n - i - 1]);
}
int res = 0;
for (int i = 0; i < n; i++) {
int left = i == 0 ? 0 : endTime[i - 1];
int right = i == n - 1 ? eventTime : startTime[i + 1];
if (q[i]) {
res = Math.max(res, right - left);
} else {
res = Math.max(res, right - left - (endTime[i] - startTime[i]));
}
}
return res;
}
}
###TypeScript
function maxFreeTime(eventTime: number, startTime: number[], endTime: number[]): number {
const n = startTime.length;
const q: boolean[] = new Array(n).fill(false);
let t1 = 0, t2 = 0;
for (let i = 0; i < n; i++) {
if (endTime[i] - startTime[i] <= t1) {
q[i] = true;
}
t1 = Math.max(t1, startTime[i] - (i === 0 ? 0 : endTime[i - 1]));
if (endTime[n - i - 1] - startTime[n - i - 1] <= t2) {
q[n - i - 1] = true;
}
t2 = Math.max(t2, (i === 0 ? eventTime : startTime[n - i]) - endTime[n - i - 1]);
}
let res = 0;
for (let i = 0; i < n; i++) {
const left = i === 0 ? 0 : endTime[i - 1];
const right = i === n - 1 ? eventTime : startTime[i + 1];
if (q[i]) {
res = Math.max(res, right - left);
} else {
res = Math.max(res, right - left - (endTime[i] - startTime[i]));
}
}
return res;
}
###JavaScript
var maxFreeTime = function(eventTime, startTime, endTime) {
const n = startTime.length;
const q = new Array(n).fill(false);
let t1 = 0, t2 = 0;
for (let i = 0; i < n; i++) {
if (endTime[i] - startTime[i] <= t1) {
q[i] = true;
}
t1 = Math.max(t1, startTime[i] - (i === 0 ? 0 : endTime[i - 1]));
if (endTime[n - i - 1] - startTime[n - i - 1] <= t2) {
q[n - i - 1] = true;
}
t2 = Math.max(t2, (i === 0 ? eventTime : startTime[n - i]) - endTime[n - i - 1]);
}
let res = 0;
for (let i = 0; i < n; i++) {
const left = i === 0 ? 0 : endTime[i - 1];
const right = i === n - 1 ? eventTime : startTime[i + 1];
if (q[i]) {
res = Math.max(res, right - left);
} else {
res = Math.max(res, right - left - (endTime[i] - startTime[i]));
}
}
return res;
};
###C#
public class Solution {
public int MaxFreeTime(int eventTime, int[] startTime, int[] endTime) {
int n = startTime.Length;
bool[] q = new bool[n];
int t1 = 0, t2 = 0;
for (int i = 0; i < n; i++) {
if (endTime[i] - startTime[i] <= t1) {
q[i] = true;
}
t1 = Math.Max(t1, startTime[i] - (i == 0 ? 0 : endTime[i - 1]));
if (endTime[n - i - 1] - startTime[n - i - 1] <= t2) {
q[n - i - 1] = true;
}
t2 = Math.Max(t2, (i == 0 ? eventTime : startTime[n - i]) - endTime[n - i - 1]);
}
int res = 0;
for (int i = 0; i < n; i++) {
int left = i == 0 ? 0 : endTime[i - 1];
int right = i == n - 1 ? eventTime : startTime[i + 1];
if (q[i]) {
res = Math.Max(res, right - left);
} else {
res = Math.Max(res, right - left - (endTime[i] - startTime[i]));
}
}
return res;
}
}
###C
int maxFreeTime(int eventTime, int* startTime, int startTimeSize, int* endTime, int endTimeSize) {
int n = startTimeSize;
bool* q = (bool*)calloc(n, sizeof(bool));
int t1 = 0, t2 = 0;
for (int i = 0; i < n; i++) {
if (endTime[i] - startTime[i] <= t1) {
q[i] = true;
}
t1 = fmax(t1, startTime[i] - (i == 0 ? 0 : endTime[i - 1]));
if (endTime[n - i - 1] - startTime[n - i - 1] <= t2) {
q[n - i - 1] = true;
}
t2 = fmax(t2, (i == 0 ? eventTime : startTime[n - i]) - endTime[n - i - 1]);
}
int res = 0;
for (int i = 0; i < n; i++) {
int left = i == 0 ? 0 : endTime[i - 1];
int right = i == n - 1 ? eventTime : startTime[i + 1];
if (q[i]) {
res = fmax(res, right - left);
} else {
res = fmax(res, right - left - (endTime[i] - startTime[i]));
}
}
free(q);
return res;
}
###Rust
impl Solution {
pub fn max_free_time(event_time: i32, start_time: Vec<i32>, end_time: Vec<i32>) -> i32 {
let n = start_time.len();
let mut q = vec![false; n];
let mut t1 = 0;
let mut t2 = 0;
for i in 0..n {
if end_time[i] - start_time[i] <= t1 {
q[i] = true;
}
t1 = t1.max(start_time[i] - if i == 0 { 0 } else { end_time[i - 1] });
let j = n - i - 1;
if end_time[j] - start_time[j] <= t2 {
q[j] = true;
}
t2 = t2.max(if i == 0 { event_time } else { start_time[n - i] } - end_time[j]);
}
let mut res = 0;
for i in 0..n {
let left = if i == 0 { 0 } else { end_time[i - 1] };
let right = if i == n - 1 { event_time } else { start_time[i + 1] };
if q[i] {
res = res.max(right - left);
} else {
res = res.max(right - left - (end_time[i] - start_time[i]));
}
}
res
}
}
复杂度分析
-
时间复杂度:$O(n)$,其中 $n$ 是所有会议的数目。
-
空间复杂度:$O(n)$。
方法二:贪心 + 优化
方法一中使用了 $q[i]$ 来判断会议 $i$ 平移的最优解,如果我们在枚举会议 $i$ 的过程中对会议 $i$ 平移的两种情况进行计算,那么就可以去掉数组 $q$。具体过程如下:
-
枚举平移的会议,将该会议左右两侧相邻的空余时间段进行合并,计算得到的新的空余时间段的时长。
-
从左到右枚举平移的会议,同时用 $t_1$ 记录当前遍历到的会议左侧非相邻的空余时间段的最大时长,如果当前会议时长小于等于 $t_1$,那么说明该会议可以平移到 $t_1$ 对应的空余时间段,计算平移后得到的新的空余时间段的时长。
-
从右到左枚举平移的会议,同时用 $t_2$ 记录当前遍历到的会议右侧非相邻的空余时间段的最大时长,如果当前会议时长小于等于 $t_2$,那么说明该会议可以平移到 $t_2$ 对应的空余时间段,计算平移后得到的新的空余时间段的时长。
返回以上所有新的空余时间段时长的最大值。
###C++
class Solution {
public:
int maxFreeTime(int eventTime, vector<int>& startTime, vector<int>& endTime) {
int n = startTime.size(), res = 0;
for (int i = 0, t1 = 0, t2 = 0; i < n; i++) {
int left1 = i == 0 ? 0 : endTime[i - 1];
int right1 = i == n - 1 ? eventTime : startTime[i + 1];
if (endTime[i] - startTime[i] <= t1) {
res = max(res, right1 - left1);
}
t1 = max(t1, startTime[i] - (i == 0 ? 0 : endTime[i - 1]));
res = max(res, right1 - left1 - (endTime[i] - startTime[i]));
int left2 = i == n - 1 ? 0 : endTime[n - i - 2];
int right2 = i == 0 ? eventTime : startTime[n - i];
if (endTime[n - i - 1] - startTime[n - i - 1] <= t2) {
res = max(res, right2 - left2);
}
t2 = max(t2, (i == 0 ? eventTime : startTime[n - i]) - endTime[n - i - 1]);
}
return res;
}
};
###Go
func maxFreeTime(eventTime int, startTime []int, endTime []int) int {
n := len(startTime)
q := make([]bool, n)
t1, t2 := 0, 0
for i := 0; i < n; i++ {
if endTime[i] - startTime[i] <= t1 {
q[i] = true
}
if i == 0 {
t1 = max(t1, startTime[i])
} else {
t1 = max(t1, startTime[i] - endTime[i - 1])
}
if endTime[n - i - 1] - startTime[n - i - 1] <= t2 {
q[n - i - 1] = true
}
if i == 0 {
t2 = max(t2, eventTime - endTime[n - 1])
} else {
t2 = max(t2, startTime[n - i] - endTime[n - i - 1])
}
}
res := 0
for i := 0; i < n; i++ {
left := 0
if i != 0 {
left = endTime[i - 1]
}
right := eventTime
if i != n - 1 {
right = startTime[i + 1]
}
if q[i] {
res = max(res, right - left)
} else {
res = max(res, right - left - (endTime[i] - startTime[i]))
}
}
return res
}
###Python
class Solution:
def maxFreeTime(self, eventTime: int, startTime: list[int], endTime: list[int]) -> int:
n = len(startTime)
q = [False] * n
t1 = 0
t2 = 0
for i in range(n):
if endTime[i] - startTime[i] <= t1:
q[i] = True
t1 = max(t1, startTime[i] - (0 if i == 0 else endTime[i - 1]))
if endTime[n - i - 1] - startTime[n - i - 1] <= t2:
q[n - i - 1] = True
t2 = max(t2, (eventTime if i == 0 else startTime[n - i]) - endTime[n - i - 1])
res = 0
for i in range(n):
left = 0 if i == 0 else endTime[i - 1]
right = eventTime if i == n - 1 else startTime[i + 1]
if q[i]:
res = max(res, right - left)
else:
res = max(res, right - left - (endTime[i] - startTime[i]))
return res
###Java
class Solution {
public int maxFreeTime(int eventTime, int[] startTime, int[] endTime) {
int n = startTime.length;
boolean[] q = new boolean[n];
for (int i = 0, t1 = 0, t2 = 0; i < n; i++) {
if (endTime[i] - startTime[i] <= t1) {
q[i] = true;
}
t1 = Math.max(t1, startTime[i] - (i == 0 ? 0 : endTime[i - 1]));
if (endTime[n - i - 1] - startTime[n - i - 1] <= t2) {
q[n - i - 1] = true;
}
t2 = Math.max(t2, (i == 0 ? eventTime : startTime[n - i]) - endTime[n - i - 1]);
}
int res = 0;
for (int i = 0; i < n; i++) {
int left = i == 0 ? 0 : endTime[i - 1];
int right = i == n - 1 ? eventTime : startTime[i + 1];
if (q[i]) {
res = Math.max(res, right - left);
} else {
res = Math.max(res, right - left - (endTime[i] - startTime[i]));
}
}
return res;
}
}
###TypeScript
function maxFreeTime(eventTime: number, startTime: number[], endTime: number[]): number {
const n = startTime.length;
const q: boolean[] = new Array(n).fill(false);
let t1 = 0, t2 = 0;
for (let i = 0; i < n; i++) {
if (endTime[i] - startTime[i] <= t1) {
q[i] = true;
}
t1 = Math.max(t1, startTime[i] - (i === 0 ? 0 : endTime[i - 1]));
if (endTime[n - i - 1] - startTime[n - i - 1] <= t2) {
q[n - i - 1] = true;
}
t2 = Math.max(t2, (i === 0 ? eventTime : startTime[n - i]) - endTime[n - i - 1]);
}
let res = 0;
for (let i = 0; i < n; i++) {
const left = i === 0 ? 0 : endTime[i - 1];
const right = i === n - 1 ? eventTime : startTime[i + 1];
if (q[i]) {
res = Math.max(res, right - left);
} else {
res = Math.max(res, right - left - (endTime[i] - startTime[i]));
}
}
return res;
}
###JavaScript
var maxFreeTime = function(eventTime, startTime, endTime) {
const n = startTime.length;
const q = new Array(n).fill(false);
let t1 = 0, t2 = 0;
for (let i = 0; i < n; i++) {
if (endTime[i] - startTime[i] <= t1) {
q[i] = true;
}
t1 = Math.max(t1, startTime[i] - (i === 0 ? 0 : endTime[i - 1]));
if (endTime[n - i - 1] - startTime[n - i - 1] <= t2) {
q[n - i - 1] = true;
}
t2 = Math.max(t2, (i === 0 ? eventTime : startTime[n - i]) - endTime[n - i - 1]);
}
let res = 0;
for (let i = 0; i < n; i++) {
const left = i === 0 ? 0 : endTime[i - 1];
const right = i === n - 1 ? eventTime : startTime[i + 1];
if (q[i]) {
res = Math.max(res, right - left);
} else {
res = Math.max(res, right - left - (endTime[i] - startTime[i]));
}
}
return res;
};
###C#
public class Solution {
public int MaxFreeTime(int eventTime, int[] startTime, int[] endTime) {
int n = startTime.Length;
bool[] q = new bool[n];
int t1 = 0, t2 = 0;
for (int i = 0; i < n; i++) {
if (endTime[i] - startTime[i] <= t1) {
q[i] = true;
}
t1 = Math.Max(t1, startTime[i] - (i == 0 ? 0 : endTime[i - 1]));
if (endTime[n - i - 1] - startTime[n - i - 1] <= t2) {
q[n - i - 1] = true;
}
t2 = Math.Max(t2, (i == 0 ? eventTime : startTime[n - i]) - endTime[n - i - 1]);
}
int res = 0;
for (int i = 0; i < n; i++) {
int left = i == 0 ? 0 : endTime[i - 1];
int right = i == n - 1 ? eventTime : startTime[i + 1];
if (q[i]) {
res = Math.Max(res, right - left);
} else {
res = Math.Max(res, right - left - (endTime[i] - startTime[i]));
}
}
return res;
}
}
###C
int maxFreeTime(int eventTime, int* startTime, int startTimeSize, int* endTime, int endTimeSize) {
int n = startTimeSize;
bool* q = (bool*)calloc(n, sizeof(bool));
int t1 = 0, t2 = 0;
for (int i = 0; i < n; i++) {
if (endTime[i] - startTime[i] <= t1) {
q[i] = true;
}
t1 = fmax(t1, startTime[i] - (i == 0 ? 0 : endTime[i - 1]));
if (endTime[n - i - 1] - startTime[n - i - 1] <= t2) {
q[n - i - 1] = true;
}
t2 = fmax(t2, (i == 0 ? eventTime : startTime[n - i]) - endTime[n - i - 1]);
}
int res = 0;
for (int i = 0; i < n; i++) {
int left = i == 0 ? 0 : endTime[i - 1];
int right = i == n - 1 ? eventTime : startTime[i + 1];
if (q[i]) {
res = fmax(res, right - left);
} else {
res = fmax(res, right - left - (endTime[i] - startTime[i]));
}
}
free(q);
return res;
}
###Rust
impl Solution {
pub fn max_free_time(event_time: i32, start_time: Vec<i32>, end_time: Vec<i32>) -> i32 {
let n = start_time.len();
let mut q = vec![false; n];
let mut t1 = 0;
let mut t2 = 0;
for i in 0..n {
if end_time[i] - start_time[i] <= t1 {
q[i] = true;
}
t1 = t1.max(start_time[i] - if i == 0 { 0 } else { end_time[i - 1] });
let j = n - i - 1;
if end_time[j] - start_time[j] <= t2 {
q[j] = true;
}
t2 = t2.max(if i == 0 { event_time } else { start_time[n - i] } - end_time[j]);
}
let mut res = 0;
for i in 0..n {
let left = if i == 0 { 0 } else { end_time[i - 1] };
let right = if i == n - 1 { event_time } else { start_time[i + 1] };
if q[i] {
res = res.max(right - left);
} else {
res = res.max(right - left - (end_time[i] - start_time[i]));
}
}
res
}
}
复杂度分析
-
时间复杂度:$O(n)$,其中 $n$ 是所有会议的数目。
-
空间复杂度:$O(1)$。