【代码随想录|刷题记录Day37】738.单调递增的数字、968.监控二叉树

90 阅读2分钟

题目列表

  738.单调递增的数字

  968.监控二叉树

解题过程

1、738.单调递增的数字

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

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

思路: 从后向前遍历,如果strNum[i - 1] > strNum[i]的情况(非单调递增),首先想让strNum[i - 1]减一,strNum[i]赋值9。

class Solution {
    public int monotoneIncreasingDigits(int n) {
        String[] strings = (n + "").split("");
        int start = strings.length;
        for (int i = strings.length - 1; i > 0; i--) {
            if (Integer.parseInt(strings[i]) < Integer.parseInt(strings[i - 1])) {
                strings[i - 1] = (Integer.parseInt(strings[i - 1]) - 1) + "";
                start = i;
            }
        }
        for (int i = start; i < strings.length; i++) {
            strings[i] = "9";
        }
        return Integer.parseInt(String.join("", strings));
    }
}

在原数组上直接修改,耗时更少

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));
    }
}

2、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) {
            return 0;
        } else if (left == 0 || right == 0) {
            // 左右节点至少有一个无覆盖,那么根节点应该放一个摄像头
            res++;
            return 1;
        } else {
            // 左右节点至少有一个摄像头,说明该根节点被覆盖了
            return 2;
        }
    }
}

注意: 分的情况有点多。

总结

贪心结束啦,最近刷题有点不太认真,很多题感觉之后都需要二刷呜呜呜。

以及,纪念力扣刷了100题啦。