【代码随想录Day37】贪心算法

738 单调递增的数字

https://leetcode.cn/problems/monotone-increasing-digits/

从左向右,在第一个递减数前找有几个递增和几个相同,789998, 6位数,5个非递减数,2个相同的9,答案789000 - 1,两个corner case : 1, 只有1一位数,2,整个都无递减时就是n。

class Solution { 
    public int monotoneIncreasingDigits(int n) {
        if (n < 10) return n;          // corner case
        int copy = n;
        Deque num = new ArrayDeque<>();
        while (n > 0) {
            num.offerLast(n % 10);
            n /= 10;
        }
        int size = num.size();
        int count = 1;
        int same = 0;
        int digit = num.pollLast();
        while (!num.isEmpty()) {
            int next = num.pollLast();
            if (digit <= next) {
                count++; {
                    if (digit < next) {
                        same = 0;
                    } else {
                        same++;
                    }
                }
            } else { //(digit > next) 
                break;
            }
            digit = next;
        }
        return size ==  count ? copy : copy / (int)Math.pow(10, size - count + same) * (int)Math.pow(10, size - count + same) - 1;
    }
}

714 买卖股票的最佳时机含手续费

https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/ DP解法

class Solution {
    public int maxProfit(int[] prices, int fee) {
        int hold = - prices[0];
        int unhold = 0;
        for (int i = 1; i < prices.length; i++) {
            int temp = hold;
            hold = Math.max(hold, unhold - prices[i]);
            unhold = Math.max(temp + prices[i] - fee, unhold);
        }
        return unhold;
    }
}

968 监控二叉树

https://leetcode.cn/problems/binary-tree-cameras/

DP,做的时候卡壳在推理关系。

class Solution {      // return int[]{total min cameras on my tree when parent has camera, kid have camera, I have camera}
    public int minCameraCover(TreeNode root) {
        int[] result = minCover(root);
        return Math.min(result[1], result[2]);
    }
    private int[] minCover(TreeNode root) {
        if (root == null) return new int[]{0, 0, Integer.MAX_VALUE / 4};
        int[] leftResult = minCover(root.left);
        int[] rightResult = minCover(root.right);
        //0, 被父节点看
        //1, 被子节点看
        //2, 被自己看
        return new int[]{
            Math.min(leftResult[1], leftResult[2]) + Math.min(rightResult[1], rightResult[2]),   //父节点看,儿子可以是1/2
            Math.min(leftResult[2] + Math.min(rightResult[1], rightResult[2]), rightResult[2] + Math.min(leftResult[1], leftResult[2])), //一个儿子看,另一个儿子可以1/2
            Math.min(Math.min(leftResult[0], leftResult[1]), leftResult[2]) + Math.min(Math.min(rightResult[0], rightResult[1]), rightResult[2]) + 1 //自己可以看,儿子可以0/1/2
        };
    }
}

你可能感兴趣的:(代码随想录,leetcode,算法)