代码随想录算法训练营 day 37: ● 738.单调递增的数字 ● 968.监控二叉树 ● 总结

47 阅读2分钟

738. Monotone Increasing Digits

这题没思路。主要思路是若前一位比当前位大,则当前位变为9, 前一位减一。edge case是连续多位为0的情况。需要一个index来记录为0的起始位。

class Solution {
    public int monotoneIncreasingDigits(int n) {
        String s[] = (n + "").split("");

        if(s.length == 1) {
            return n;
        }

        int carry = 0;
        int start = s.length;

        for(int i=s.length - 1; i>0; i--) {
            int cur = Integer.parseInt(s[i]);
            int pre = Integer.parseInt(s[i-1]) - carry;

            if(pre > cur) {
                s[i-1] = String.valueOf(pre - 1);
                start = i;
            }
        }

        for(int i=start; i<s.length; i++) {
            s[i] = "9";
        }

        return Integer.parseInt(String.join("", s));


     }
}

968. Binary Tree Cameras

这题要把所有的情形列清楚。

  • 情况1:左右节点都有覆盖

左孩子有覆盖,右孩子有覆盖,那么此时中间节点应该就是无覆盖的状态了。

  • 情况2:左右节点至少有一个无覆盖的情况

如果是以下情况,则中间节点(父节点)应该放摄像头:

  • left == 0 && right == 0 左右节点无覆盖
  • left == 1 && right == 0 左节点有摄像头,右节点无覆盖
  • left == 0 && right == 1 左节点有无覆盖,右节点摄像头
  • left == 0 && right == 2 左节点无覆盖,右节点覆盖
  • left == 2 && right == 0 左节点覆盖,右节点无覆盖

这个不难理解,毕竟有一个孩子没有覆盖,父节点就应该放摄像头。

此时摄像头的数量要加一,并且return 1,代表中间节点放摄像头。

  • 情况3:左右节点至少有一个有摄像头

如果是以下情况,其实就是 左右孩子节点有一个有摄像头了,那么其父节点就应该是2(覆盖的状态)

  • left == 1 && right == 2 左节点有摄像头,右节点有覆盖
  • left == 2 && right == 1 左节点有覆盖,右节点有摄像头
  • left == 1 && right == 1 左右节点都有摄像头

情形列全了,代码不难写。

/**
 * 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 res = 0;
    //0: no cover
    //1: camera
    //2: covered
    public int traversal(TreeNode root) {
        if(root == null) {
            return 2;
        }

        int left = traversal(root.left);
        int right = traversal(root.right);


        //left 2 right 2
        if(left == 2 && right == 2) {
            return 0;
        }

        //left 0, right 1
        //left 0 right 0
        //left 1, right 0
        if(left == 0 || right == 0) {
            res++;
            return 1;
        }

        // (1,0), (1,1), (0,1), (1,2),(2,1)
        if(left == 1 || right == 1) {
            return 2;
        }

        return -1;
    }

    public int minCameraCover(TreeNode root) {
        res = 0;

        if(traversal(root) == 0) {
            res++;
        }

        return res;
    }

}