LeetCode Day36|●56. 合并区间(先存起来)● 738.单调递增的数字(从后往前变量,flag的妙用)● 968.监控二叉树(二叉树+贪心)

day36-1 ●56. 合并区间

题意

在这里插入图片描述

解题思路

不要在原数组进行操作,在原数组上操作会非常复杂,不仅合并两个数组数组后要插入新的数组而且还有删除原来的两个数组

代码实现

class Solution {
	/**
	*时间复杂度: O(nlogn)
	*空间复杂度: O(logn),排序需要的空间开销
	*/
    public int[][] merge(int[][] intervals) {
        List<int[]> result = new ArrayList<>();
        // 除掉特殊情况
        if (intervals.length == 0) {
            return result.toArray(new int[][]{});
        }
        // 根据左区间进行排序
        Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0]));
        result.add(intervals[0]);
        for (int i = 1; i < intervals.length; i++) {
            // 合并区间
            if (result.get(result.size() - 1)[1] >= intervals[i][0]) {
                // 取最大的右区间
                result.get(result.size() - 1)[1] = Math.max(result.get(result.size() - 1)[1], intervals[i][1]);
            // 添加元素
            }else {
                result.add(intervals[i]);
            }
        }
        return result.toArray(new int[][]{});
    }
}

总结

重叠类问题:排序—>重叠(1.重叠怎么处理 2.没有重叠怎么处理)

day36-2 ● 738.单调递增的数字

题意

关键点:
大于等于
单调递增

理解思路

遍历顺序从后往前
flag的秒用

模拟过程

在这里插入图片描述

代码实现

class Solution {
    public int monotoneIncreasingDigits(int n) {
        String s = String.valueOf(n);
        char[] chars = s.toCharArray();
        // flag 有秒用,如果是1234的情况,就不会走下面的两段for循环的逻辑
        int flag = s.length();
        for (int i = s.length() - 1; i > 0; i--) {
            if (chars[i - 1] > chars[i]) {
                chars[i - 1]--;
                flag = i;
            }
        }
        for (int i = flag; i < s.length(); i++) {
            chars[i] = '9';
        }
        //return Integer.parseInt(String.valueOf(chars));
        return Integer.parseInt(new String(chars));
    }
}

总结

遍历顺序:只有从后向前遍历才能重复利用上一次比较的结果

day36-3 ● 968.监控二叉树 (可跳过)

题意

每天摄像头可以监视其父对象、自身、及其直接子对象
使用最少的摄像头数量
叶子节点不要放摄像头,要重复利用摄像头的监控范围
在这里插入图片描述

解题思路

优先从叶子节点的父节点开始去安装摄像头,然后每隔两个节点按照一个摄像头

节点状态

0: 无覆盖
1: 有摄像头
2: 有覆盖
无摄像头的状态已近被0(无覆盖)和2(有覆盖)的状态覆盖掉了
null节点应该是有覆盖状态才不违背贪心的初衷
三种情况:
在这里插入图片描述

特殊情况(根节点没有摄像头)没有考虑:
在这里插入图片描述

代码实现

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    int result = 0;
    public int minCameraCover(TreeNode root) {
        if(traveral(root) == 0){
            result++;
        }
        return result;
    }
    /**
     * 节点状态:
     * 0: 无覆盖
     * 1: 有摄像头
     * 2: 有覆盖
     */
    public int traveral(TreeNode cur){
        // 保证叶子节点为无覆盖
        if(cur == null){
            return 2;
        }
        // 左
        int left = traveral(cur.left);
        // 右
        int right = traveral(cur.right);
        // 中
        // 左右都覆盖
        if(left == 2 && right == 2){
            return 0;
        }
        // 左右至少有一个无覆盖
        if(left == 0 || right == 0){
            result++;
            return 1;
        }
        // 左右至少有覆盖
        if(left == 1 || right == 1){
            return 2;
        }
        return -1;
    }
}

总结

  • 优先从叶子节点的父节点开始去安装摄像头,然后每隔两个节点按照一个摄像头
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值