【前端er每日算法】贪心2题--738/968

66 阅读1分钟

题目一 738. 单调递增的数字

思路

如果前一个数字比当前数字大,则前一个数字减1,并且之后的所有数字要变成9,所以要记录当前位置,作为改成9的起始位置,最后改变数组,获得result。

var monotoneIncreasingDigits = function(n) {
    const arr = ('' + n).split('').map(item => +item);
    const len = arr.length;
    let flag = len;
    for (let i = len - 1; i > 0; i--) {
        if (arr[i - 1] > arr[i]) {
            arr[i - 1] = arr[i-1] - 1;
            flag = i;
        }
    }
    let result = 0;
    for (let i = 0; i < arr.length; i++) {
        if (i >= flag) {
            arr[i] = 9;
        }
        result = result * 10 + arr[i];
    }
    return result;
};

题目二 968. 监控二叉树

思路

状态值:0: 无覆盖 1: 有摄像头 2: 有覆盖

状态转移:

  1. 叶子节点返回有覆盖2,因为父节点要安装摄像头
  2. 如果左右2个子节点都有覆盖,则父节点为无覆盖为0
  3. 如果左孩子或者右孩子,有一个未覆盖,则父节点需要安装摄像头,返回1,result++
  4. 如果左孩子或者右孩子有一个有摄像头,则父节点有覆盖,返回2
  5. 最后根节点,如果返回了0,则需要添加一个摄像头,result++
var minCameraCover = function(root) {
    let result = 0;
    // 0: 无覆盖 1: 有摄像头 2: 有覆盖
    var traverse = root => {
        // 叶子节点返回有覆盖
        if (!root) {
            return 2;
        }
        const left = traverse(root.left);
        const right = traverse(root.right);
        // 如果左右都覆盖了,那root无覆盖
        if (left === 2 && right === 2) {
            return 0;
        }
        // 如果左和右,有一个没覆盖,则+1
        if (left === 0 || right === 0) {
            result++;
            return 1;
        }
        // 如果左和右,有一个有摄像头
        if (left === 1 || right === 1) {
            return 2;
        }
        return -1;
    }
    if (traverse(root) === 0) {
        result++;
    }

    return result;
};