题目
56. 合并区间
题解:
class Solution {
public int[][] merge(int[][] intervals) {
if (intervals.length == 0) return new int[0][0]; // 特殊情况处理
List<int[]> ansList = new ArrayList<>();
// 1. 排序
Arrays.sort(intervals, (a,b) -> Integer.compare(a[0], b[0]));
for(int i = 1; i < intervals.length; i++) {
// 2. 判断重叠
if(intervals[i][0] <= intervals[i-1][1]) {
// 有重叠:合并
// 把前一个的 start 传给当前 (保持最小 start)
intervals[i][0] = intervals[i-1][0];
// 更新当前的 end 为两者最大 end
intervals[i][1] = Math.max(intervals[i][1], intervals[i-1][1]);
// 注意:这里不添加进 list,因为这个合并后的新区间可能还会和后面重叠
} else {
// 无重叠:说明 i-1 已经处理完毕,可以安全加入结果集
ansList.add(intervals[i-1]);
}
}
// 3. 循环结束后,必须把最后一个区间加入
// 无论它是被合并过的,还是独立的,它都还留在 intervals 数组的最后一位
ansList.add(intervals[intervals.length - 1]);
// 4. 转为二维数组
return ansList.toArray(new int[ansList.size()][]);
}
}
738. 单调递增的数字
题解:
class Solution {
public int monotoneIncreasingDigits(int n) {
String s = String.valueOf(n);
char[] chars = s.toCharArray();
// start 用来记录从哪里开始把后面全变成 9
// 初始化为 length,防止不需要变的情况(如 1234)
int start = chars.length;
// 1. 从后向前遍历
for (int i = chars.length - 1; i > 0; i--) {
// 如果前一位 > 后一位(出现逆序)
if (chars[i - 1] > chars[i]) {
// 前一位减 1
chars[i - 1]--;
// 记录当前位置 i 为“变成9的起始点”
start = i;
}
}
// 2. 统一将标记点之后的所有位变成 9
// 这一步必须放在循环外面做,因为 start 可能会不断向前更新
// 比如 100 -> 099,如果不更新 start,可能中间会有没变成 9 的
for (int i = start; i < chars.length; i++) {
chars[i] = '9';
}
return Integer.parseInt(new String(chars));
}
}
968. 监控二叉树
题解:
class Solution {
int res = 0; // 记录摄像头数量
public int minCameraCover(TreeNode root) {
// 后序遍历(从下往上)
// 如果最后根节点返回 0 (无覆盖),说明根节点需要一个摄像头
if (minCameraCoverDfs(root) == 0) {
res++;
}
return res;
}
/**
* @return
* 0: 无覆盖 (Not Covered)
* 1: 有摄像头 (Has Camera)
* 2: 已覆盖 (Covered)
*/
private int minCameraCoverDfs(TreeNode node) {
// Base Case: 空节点视为“已覆盖”,这样叶子节点就会被判断为“无覆盖”
if (node == null) return 2;
int left = minCameraCoverDfs(node.left);
int right = minCameraCoverDfs(node.right);
// 逻辑顺序很重要,必须先判断是否需要装摄像头
// Case 1: 左右孩子只要有一个没被覆盖,我就必须装摄像头
if (left == 0 || right == 0) {
res++;
return 1; // 我装了摄像头
}
// Case 2: 左右孩子只要有一个有摄像头,我就被覆盖了
// (前提是 Case 1 不满足,说明没有孩子是 0)
if (left == 1 || right == 1) {
return 2; // 我被覆盖了
}
// Case 3: 左右孩子都是已覆盖 (2),那我就没人管了
// 我变成了无覆盖,等待父节点处理
return 0;
}
}

1200

被折叠的 条评论
为什么被折叠?



