LeetCode刷题 Day37

100 阅读3分钟

LeetCode刷题 Day37

738. Monotone Increasing Digits

An integer has monotone increasing digits if and only if each pair of adjacent digits x and y satisfy x <= y.

Given an integer n, return the largest number that is less than or equal to n with monotone increasing digits.

 

Example 1:

Input: n = 10
Output: 9

Example 2:

Input: n = 1234
Output: 1234

Example 3:

Input: n = 332
Output: 299

思路:

  1. 暴力法,从右往左遍历,当出现n[i -1] > n[i]时,n--,但是这种方法会超时。
  2. greedy方法:
    • 从右往左遍历, 当n[i - 1] > n[i]时,记录i,然后n[i-1]--, n[i] = 9。这样保证i这个位置的值是最大的。
    • 然后从i开始,从左往右顺序遍历。将i之后的值都变成9。保证其之后右边的值都是9。

代码:

var monotoneIncreasingDigits = function(n) {
    n = n.toString();
    n = n.split('').map(item => {
        return +item;
    });

    let flag = Number.MAX_VALUE;

    for (let i = n.length - 1; i > 0; i--) {
        if (n[i - 1] > n[i]) {
            flag = i;
            n[i - 1] = n[i - 1] - 1;
            n[i] = 9;
        }
    }
    for (let i = flag; i < n.length; i++) {
        n[i] = 9;
    }
    n = n.join('');
    return Number(n)
};

时间复杂度: O(n), 空间复杂度: O(n)


714. Best Time to Buy and Sell Stock with Transaction Fee

You are given an array prices where prices[i] is the price of a given stock on the ith day, and an integer fee representing a transaction fee.

Find the maximum profit you can achieve. You may complete as many transactions as you like, but you need to pay the transaction fee for each transaction.

Note:  You may not engage in multiple transactions simultaneously (i.e., you must sell the stock before you buy again).

 

Example 1:

Input: prices = [1,3,2,8,4,9], fee = 2
Output: 8
Explanation: The maximum profit can be achieved by:
- Buying at prices[0] = 1
- Selling at prices[3] = 8
- Buying at prices[4] = 4
- Selling at prices[5] = 9
The total profit is ((8 - 1) - 2) + ((9 - 4) - 2) = 8.

Example 2:

Input: prices = [1,3,7,5,10,3], fee = 3
Output: 6

思路:

  • 贪心法: 不容易想到,跳过
  • dp, 先定义持有和不持有两个变量,然后通过计算持有和不持有每天的最优情况来获取最大值

代码:

var maxProfit = function(prices, fee) {
    let have = -prices[0] - fee;
    let notHave = 0;

    for (let i = 1; i < prices.length; i++) {
        // i day, have stock
        have = Math.max(have, notHave - prices[i] - fee);
        // i day, doesn't have stock
        notHave = Math.max(have + prices[i], notHave);
    }

    return notHave;
};
  • 时间复杂度: O(n) 空间复杂度: O(1)

968. Binary Tree Cameras

You are given the root of a binary tree. We install cameras on the tree nodes where each camera at a node can monitor its parent, itself, and its immediate children.

Return the minimum number of cameras needed to monitor all nodes of the tree.

Example 1:

Input: root = [0,0,null,0,0]
Output: 1
Explanation: One camera is enough to monitor all nodes if placed as shown.

Example 2:

Input: root = [0,0,null,0,null,0,null,null,0]
Output: 2
Explanation: At least two cameras are needed to monitor all nodes of the tree. The above image shows one of the valid configurations of camera placement.

思路:

  • 考虑清楚需要的场景:
    1. 是否需要覆盖空节点,如果不覆盖,那么叶子节点就需要安装摄像头。所以需要覆盖
    2. 其中一个子节点没有被覆盖,则当前节点需要安装摄像头,告诉父节点自己有摄像头。 res++, return 1
    3. 两个子节点都被覆盖,则可以跳过当前节点, 但是要告诉父节点自己未被覆盖 return 0
    4. 有一个子节点安装了摄像头,则跳过当前节点,告诉父节点已经被覆盖, return 2
    5. 最后要注意root节点是否被覆盖。有可能未被覆盖,如果未被覆盖则要res++。
  • 数字注释: 未被覆盖: 0 安装摄像头: 1 覆盖: 2 代码:
var minCameraCover = function(root) {
    let res =  0;
    var helper = function(root) {
        if (!root) return 2;

        const left = helper(root.left);
        const right =  helper(root.right);

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

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

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

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

    return res;
};

时间复杂度: O(n) 空间复杂度: O(n)