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

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


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

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


你可能感兴趣的:(训练营,算法,leetcode,职场和发展)