Day 37 | 738.单调递增的数字 & 714. 买卖股票的最佳时机含手续费 & 968.监控二叉树

738.单调递增的数字

贪心解题思路:

        如果从前向后遍历的话,修改了的数值可能又会大于前面的数值。因此从后向前遍历,定义标记变量flag找到非递增的最靠前位置,将nums[i]--,i之后的数都设为9即可。

    public int monotoneIncreasingDigits(int n) {
        String s = String.valueOf(n);
        char[] ss = s.toCharArray();
        int flag = ss.length;
        for (int i = 0; i <ss.length-1; i++) {
            //如果这里不递增,将ss[i]-1,记录i+1的位置
            //遍历结束后,flag为不递增序列开始的起始位置
            if (ss[i] > ss[i + 1] || (ss[i]==ss[i+1]&&ss[i+1]>ss[i+2])) {
                while (ss[i]==ss[i+1]&&ss[i+1]>ss[i+2]){
                    i++;
                }
                ss[i]--;
                flag=i+1;
                break;
            }
        }
        //flag之后的都变成9
        for (int i = flag; i < ss.length; i++) {
            ss[i] = '9';
        }
        return Integer.parseInt(String.valueOf(ss));
    }

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

其实理解的还不是很透彻,尤其最后一步更新min的值

贪心解题思路:

        本题不用纠结是哪一天买入买出,只要卖-买-利润>0,记录到sum中即可。

        定义买入变量min的初值为price[0],遍历数组,当当前元素小于min时更新min的值

        当price[i]-min-fee<0,不做任何操作,continue。

        当price[i]-min-fee>0,则将差值添加到结果集中。此时并不一定是真正卖出,只是更新了利润值。若后面有更小的min值才是真正意义是卖出。将price[i]-fee赋值给min,如果当前不是最后一次卖出的话,就把当前减去的min加上(price[i]-(min)-fee)。若后面卖出的利润大于当前price[i]-fee,则从后面卖出。

    public int maxProfit(int[] prices, int fee) {
        int min=prices[0];
        int sum=0;
        for(int i=1;i<prices.length;i++){
            if(prices[i]<min){
                min=prices[i];
            }
            if(prices[i]>min&&prices[i]<=min+fee){
                continue;
            }
            if(prices[i]>min+fee){
                sum+=prices[i]-min-fee;
                min=prices[i]-fee;
            }
        }   
        return sum;
    }

968.监控二叉树

 这道题,看着就没思路,但是看了题解感觉还好,自己写出来代码了,嘿嘿。

首先,明确:叶子节点不能放摄像头,根节点可以有摄像头。

为什么不从根节点看起?

        因为叶子节点可以有很多个,根节点只有一个。叶子节点放的摄像头指数级增长

因此采用后序遍历,设置三个标记,0代表无覆盖,1代表有摄像头,2代表有覆盖。

        首先,当遍历到空节点时,标记为2(为了让叶子结点无覆盖)

然后会有以下三种情况:

①左右孩子有一个无覆盖0:res++,此处父节点为1放置摄像头

②左右孩子都有覆盖2:此处父节点设置为无覆盖0(当左右孩子都为null标记为2,叶子结点就为0)

③左右孩子有一个为摄像头1:此处父节点为有覆盖2。

最后遍历结束时,判断返回值是否为0,若为0则代表根节点无覆盖需要添加摄像头,res++即可。

class Solution {
    int res;
    public int minCameraCover(TreeNode root) {
        if(traversal(root)==0){
            res++;
        }
        return res;
    }
    public int traversal(TreeNode root) {
        // 0无覆盖 1有摄像头 2有覆盖
        if(root==null){return 2;}
        int left=traversal(root.left);
        int right=traversal(root.right);
        if(left==2&&right==2){return 0;}
        if(left==0||right==0){
            res++;
            return 1;
        }
        if(left==1||right==1){
            return 2;
        }
        return -1;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值