• 算法训练day37|贪心算法 part06(LeetCode738.单调递增的数字)


    738.单调递增的数字

    题目链接🔥🔥
    给定一个非负整数 N,找出小于或等于 N 的最大的整数,同时这个整数需要满足其各个位数上的数字是单调递增。
    (当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,我们称这个整数是单调递增的。)

    示例 1:
    输入: N = 10
    输出: 9

    示例 2:
    输入: N = 1234
    输出: 1234

    示例 3:
    输入: N = 332
    输出: 299
    说明: N 是在 [0, 10^9] 范围内的一个整数。

    思路分析

    暴力解法会超时。
    题目要求小于等于N的最大单调递增的整数,那么拿一个两位的数字来举例。

    例如:98,一旦出现strNum[i - 1] > strNum[i]的情况(非单调递增),首先想让strNum[i - 1]–,然后strNum[i]给为9,这样这个整数就是89,即小于98的最大的单调递增整数。

    这一点如果想清楚了,这道题就好办了。

    此时是从前向后遍历还是从后向前遍历呢?

    从前向后遍历的话,遇到strNum[i - 1] > strNum[i]的情况,让strNum[i - 1]减一,但此时如果strNum[i - 1]减一了,可能又小于strNum[i - 2]。

    这么说有点抽象,举个例子,数字:332,从前向后遍历的话,那么就把变成了329,此时2又小于了第一位的3了,真正的结果应该是299。

    那么从后向前遍历,就可以重复利用上次比较得出的结果了,从后向前遍历332的数值变化为:332 -> 329 -> 299

    确定了遍历顺序之后,那么此时局部最优就可以推出全局,找不出反例,试试贪心

    代码实现

    C++代码如下:

    class Solution {
    public:
        int monotoneIncreasingDigits(int N) {
            string strNum = to_string(N);
            // flag用来标记赋值9从哪里开始
            // 设置为这个默认值,为了防止第二个for循环在flag没有被赋值的情况下执行
            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);
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    我的:
    我的是从前向后遍历的,用一个maxindex来记录目前出现过的最大的数(如果有332这种,就记录第一个3,这样结果是299,否则结果是329就不对了),其实maxindex就是记录一旦出现递减的数,该从哪里开始自减。

    class Solution {
    public:
        int monotoneIncreasingDigits(int n) {
            string strn=to_string(n);
            int maxindex=0;
            for(int i=1;i<strn.size();i++){
                if(strn[i]>strn[i-1]) maxindex=i;
                if(strn[i]<strn[i-1]){
                    strn[maxindex]--;
                    for(int j=maxindex+1;j<strn.size();j++) strn[j]='9';
                }
            }
            int result=stoi(strn);
            return result;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

  • 相关阅读:
    Linux 文件锁的原理、实现和应用
    《Python魔法大冒险》003 两个神奇的魔法工具
    用DIV+CSS技术设计的体育篮球主题 校园体育网页与实现制作(web前端网页制作课作业)
    【文件包含】phpmyadmin 文件包含(CVE-2014-8959)
    阿里云大数据助理工程师认证考试考什么内容?
    旭日x3派上实时订阅yolov5识别到的内容并通过串口发送到stm32f10系上并通过oled实时显示的stm32代码怎么写
    C++的算法库
    7 个不容忽视的开源安全工具
    API 文档搜索引擎
    创建和删除目录( mkdir函数 和 rmdir函数 )
  • 原文地址:https://blog.csdn.net/weixin_43399263/article/details/132617722