算法训练营DAY|738.单调递增的数字、714. 买卖股票的最佳时机含手续费、968.监控二叉树

文章探讨了LeetCode上的738题,即找到比给定整数小的最大单调递增数。解题关键是从后向前遍历,遇到数位降序时,将前一位减一,其余变为9。代码实现中需注意标志位flag的使用,以及将整数转换为字符串便于操作。
摘要由CSDN通过智能技术生成

贪心的最后一期了,后两道一刷先不刷,或者等有空闲再考虑做,据说题目有些难度。


738. 单调递增的数字 - 力扣(LeetCode)https://leetcode.cn/problems/monotone-increasing-digits/题目描述很简单,就是找出比给定整数小的一个最大整数,且该整数满足最高位到最低位依次递增(可以出现相等数字)。找到的最大递增数字也可以和给定数字相等,只要满足单调递增就可以了。

详细看示例,这里分析解题思路。题目乍一看没什么理解上的难度,但是真的要分析出来,确实有些难度,并不是思路有很难,而是很难想出来。要做出来题,主要是要想清一点,给定一个数是如何求到最大的单调递增,例如给的数是98求出来的数是89,89满足小于等于98的且单调递增,而且你找不出任何比89更大的单调递增,那么它一定是符合的,322得到的是299,这两个示例看似没有共同点,实际上是暗藏玄机的。都是将一个数的最高位减一,然后其余位数变成9,就能得到了,那可有反例呢?1234就是反例,它求出的应该是1234也就是数字本身,这时我们就要加一个限制条件,先判断数字,再变化各位不要无脑变化。

具体思路是:比较各个数位,相邻数位中是否出现第一个数比第二个数大,如果出现了那说明符合之前的规律,如果如相反,则说明给出的数在目前这两位是1234这种类型的,往后遍历再试试。那问题来了,是从前向后遍历还是从后向前遍历呢?答案应该是从后向前依次遍历,如果是从前向后的话遇到了当前数据比上一位数小的情况则上一位数要减小1,那如果减小1了之后它又比之前位数小了这怎么办呢?这就出现bug了,所以不要从前向后遍历,这样会改变之前的数据,应该从后向前遍历,改变的是下一个数的值,这样就不会改变之前遍历过的数了。

具体见代码

class Solution {
public:
    int monotoneIncreasingDigits(int n) {
        string strnum=to_string(n);
        int flag=strnum.size();
        for(int i=strnum.size()-1;i>0;i--){
            if(strnum[i-1]>strnum[i]){
                flag=i;
                strnum[i-1]--;
            }
        }
        for(int i=flag;i<strnum.size();i++)
        strnum[i]='9';
        return stoi(strnum);
    }
};

看了代码后发现,其实我们所要注意的不止这些,还有flag做标记,它的作用是标记从哪一位数之后的数应该全部变为9,这一点也是相当重要的,这样的思路我们可以在全部的数位遍历完之后再去修改要改成9的位,方便了我们的操作。在操作给定数之前由于是int类型的,操作起来会有一些不方便,所以我们将其变为字符串类型,这样可以方便我们对该数进行数位上的操作。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学习算法的杨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值