城墙防线
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 192 ms, 内存: 20.0 MB
/*
* Problem Statement:
* Given an array of intervals representing ramparts, each rampart can expand to the left, right, or both directions.
* The goal is to determine the maximum expansion value such that no ramparts overlap after expansion.
* Initial intervals are non-overlapping and sorted in ascending order.
*/
import java.util.Arrays;
public class RampartExpansionStream {
public int maxExpansion(int[][] rampart) {
int left = 0, right = Integer.MAX_VALUE;
while (left < right) {
int mid = (left + right + 1) / 2;
if (canExpand(rampart, mid)) {
left = mid;
} else {
right = mid - 1;
}
}
return left;
}
private boolean canExpand(int[][] rampart, int length) {
return Arrays.stream(rampart, 1, rampart.length)
.allMatch(interval -> interval[0] - rampart[Arrays.asList(rampart).indexOf(interval) - 1][1] >= 2 * length);
}
public static void main(String[] args) {
RampartExpansionStream res = new RampartExpansionStream();
int[][] rampart1 = {{0, 3}, {4, 5}, {7, 9}};
int[][] rampart2 = {{1, 2}, {5, 8}, {11, 15}, {18, 25}};
System.out.println(res.maxExpansion(rampart1)); // Output: 3
System.out.println(res.maxExpansion(rampart2)); // Output: 4
}
}
解释
方法:
这个解法基于二分查找的方法来确定城墙可以膨胀的最大距离。首先,创建一个列表 `lst`,每个元素表示相邻城墙间的初始间隔。然后,定义一个辅助函数 `check(num)` 来验证给定的膨胀距离 `num` 是否可行,即是否能保持城墙间无重叠。`check` 函数通过逐个调整剩余的间隔来实现这一点。如果某个间隔小于 `num`,则从下一间隔中减去不足的部分。如果所有间隔都可以调整以满足条件,则返回 `True`。在主函数中,通过二分查找的方式不断调整 `num`,直到找到可能的最大膨胀距离。
时间复杂度:
O(n log n)
空间复杂度:
O(n)
代码细节讲解
🦆
在实现`check`函数时,为什么需要使用副本`temp`,而不是直接在原始的`lst`上操作?
▷🦆
二分查找中,为什么选择`right`的初始值为`min(lst[i] + lst[i - 1] for i in range(1, len(lst)))`?这样的选择有什么特殊的意义或优势吗?
▷🦆
在二分查找的过程中,如果`check(mid)`返回`True`,为什么更新`left = mid`而不是`left = mid + 1`?
▷