一、56. 合并区间
和昨天题一样的套路,以左边界排序,比较当前区间左边界和上一区间右边界(i初始为1,区间0的边界被设为begin和end的初始值)。当有重合,更新右边界的值(max比较)。无重合则将前一个区间加入集合,更新begin和end为当前区间。
class Solution {
public int[][] merge(int[][] intervals) {
Arrays.sort(intervals , (a , b) -> Integer.compare(a[0],b[0]));
List<int[]> list = new LinkedList<>();
int begin = intervals[0][0];
int end = intervals[0][1];
for(int i = 1 ; i<intervals.length ; i++){
if(intervals[i][0]<=end){
end = Math.max(intervals[i][1],end);
}else{
list.add(new int[]{begin,end});
begin = intervals[i][0];
end = intervals[i][1];
}
}
list.add(new int[]{begin,end});
return list.toArray(new int[list.size()][]);
}
}
二、738.单调递增的数字
一旦遇到前面的数比后面的小(非单调递增),就把前面这个数-1,而为了使结果最大,后面的数设为9,从哪个位置发生-1操作就要把后面全都复制为9,所以赋值的start等于i+1。
本题注意int、String、char[]之间的转换
class Solution {
public int monotoneIncreasingDigits(int n) {
String s = String.valueOf(n);
char[] cs = s.toCharArray();
int start = cs.length;
for(int i = cs.length-2 ; i>=0 ; i--){
if(cs[i]>cs[i+1]){
cs[i]--;
start=i+1;
}
}
for(int j = start; j<cs.length ; j++){
cs[j]='9';
}
return Integer.parseInt(String.valueOf(cs));
}
}
三、968.监控二叉树
将节点分为三种类型
- 无摄像头覆盖记为0
- 有摄像头记为1
- 被摄像头覆盖记为2
我们需要后序遍历从下往上处理,因为叶子结点数量多,优先考虑在叶子结点节省摄像头。
递归三要素:
- 输入输出:输入节点,输出当前节点状态
- 终止条件:遇到空节点返回状态2已覆盖,这样才能使叶子结点为0,其父节点为1
- 单层逻辑:判断左右孩子的状态决定父节点的状态
父节点状态(单层逻辑)的依据如下:
- 当左右孩子都为2,即都已经被覆盖,则返回0等待自己的父节点装摄像头
- 当任意一个孩子为0,则需要装摄像头,返回1并count+1
- 当有一个孩子为1,则返回2
显然情况2应该优先于3判断,而且1和2都不满足的时候只剩下情况3,所以用else即可,所有情况都被覆盖。
根节点的特殊情况:在递归结束后,主函数中会返回根节点的状态,如果根节点为0,那自己需要装一个摄像头。
class Solution {
int count = 0;
public int minCameraCover(TreeNode root) {
int a = traversal(root);
if(a == 0) count++;
return count;
}
private int traversal(TreeNode cur){
if(cur == null) return 2;
int left = traversal(cur.left);
int right = traversal(cur.right);
if(left==2 && right==2) return 0;
else if(left==0 || right==0){
count++;
return 1;
}
else return 2;
}
}

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



