Day28 | 56. 合并区间 738.单调递增的数字 968.监控二叉树

语言

Java

56. 合并区间

合并区间

题目

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。

思路

创建结果数组,给二维数组按照元素的第一位进行升序排序,循环遍历,看看第一个数组的右边界是不是比第二个数组的左边界小,如果是的话把他俩合并成一个新数组,数组起始位置是第一个数的左边界,终止位置是两个数右边界的最大值。不符合条件直接添加到新数组。

最后转化为二维数组。

代码

class Solution {
    public int[][] merge(int[][] intervals) {
        List<int[]> res = new ArrayList<>();
        Arrays.sort(intervals, (x, y) -> Integer.compare(x[0] ,y[0]));
        res.add(intervals[0]);
        for (int i = 1; i < intervals.length; i++) {
            if (intervals[i][0] <= res.getLast()[1]) {
                int start = res.getLast()[0];
                int end = Math.max(res.getLast()[1], intervals[i][1]);
                res.removeLast();
                res.add(new int[]{start, end});
            } else {
                res.add(intervals[i]);
            }
        }
        return res.toArray(new int[res.size()][]);
    }
}

易错点

第一点判断那里是小于等于

第二点别忘了转回为数组

738.单调递增的数字

单调递增的数字

题目

当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,我们称这个整数是单调递增的。

给定一个整数 n ,返回 小于或等于 n 的最大数字,且数字呈 单调递增 。

思路

给的数字先转化成字符串,再把字符串转化成字符数组,定义一个切割数

通过从后面的数组向前循环遍历,如何后面的数小于前面的数,就把定义的切割线向前移动一位

再把切割线后的数字都变成9,最后转化回数字。

代码

class Solution {
    public int monotoneIncreasingDigits(int n) {
        String s = String.valueOf(n);
        char[] chars = s.toCharArray();
        int start = s.length();
        for (int i = s.length() - 2; i >= 0; i--) {
            if (chars[i] > chars[i + 1]) {
                chars[i]--;
                start = i + 1;
            }
        }
        for (int i = start; i < s.length(); i++) {
            chars[i] = '9';
        }
        return Integer.parseInt(String.valueOf(chars));
    }
}

易错点

第一点是数字要减小一位,分割线要更新。

第二点是要把结果再转化为数字。

968.监控二叉树

监控二叉树

题目

给定一个二叉树,我们在树的节点上安装摄像头。

节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。

计算监控树的所有节点所需的最小摄像头数量。

思路

设置三种状态,有摄像头,无覆盖、有覆盖。

按照后序进行递归,判断三种情况

子树两边都没覆盖,子树只有一边没覆盖,子树都有覆盖,向上遍历。

返回状态,具体看代码。

代码

class Solution {
    int  res=0;
    public int minCameraCover(TreeNode root) {
        // 对根节点的状态做检验,防止根节点是无覆盖状态 .
        if(minCame(root)==0){
            res++;
        }
        return res;
    }
    /**
     节点的状态值:
       0 表示无覆盖
       1 表示 有摄像头
       2 表示有覆盖
    后序遍历,根据左右节点的情况,来判读 自己的状态
     */
    public int minCame(TreeNode root){
        if(root==null){
            // 空节点默认为 有覆盖状态,避免在叶子节点上放摄像头
            return 2;
        }
        int left=minCame(root.left);
        int  right=minCame(root.right);

        // 如果左右节点都覆盖了的话, 那么本节点的状态就应该是无覆盖,没有摄像头
        if(left==2&&right==2){
            //(2,2)
            return 0;
        }else if(left==0||right==0){
            // 左右节点都是无覆盖状态,那 根节点此时应该放一个摄像头
            // (0,0) (0,1) (0,2) (1,0) (2,0)
            // 状态值为 1 摄像头数 ++;
            res++;
            return 1;
        }else{
            // 左右节点的 状态为 (1,1) (1,2) (2,1) 也就是左右节点至少存在 1个摄像头,
            // 那么本节点就是处于被覆盖状态
            return 2;
        }
    }
}

易错点

在于情况少想了,主函数那里要控制根节点的情况。

总结

贪心算法这里就结束啦,明天开始动态规划。

成大事者,争百年,不争一息

  • 18
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值