738. 单调递增的数字-贪心算法

738. 单调递增的数字-贪心算法

题目描述

leetcode题目链接
当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,我们称这个整数是单调递增的。
给定一个整数 n ,返回 小于或等于 n 的最大数字,且数字呈 单调递增 。
示例 1:
输入: n = 10
输出: 9

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

示例 3:
输入: n = 332
输出: 299

思路

一旦出现strNum[i - 1] > strNum[i]的情况(非单调递增),首先想让strNum[i - 1]–,然后strNum[i]给为9,比如98,这样得到89就是小于98的最大的单调递增整数。
然后要考虑遍历顺序,要得到最大数字,就尽量不动左边的高位数字,所以想到从右往左遍历。

C++代码

错误版本

class Solution {
public:
    int monotoneIncreasingDigits(int n) {
        string str = std::to_string(n);
        for(int i = str.size()-1; i > 0; i--){  //string对象的长度
            if(str[i - 1] > str[i]){
                str[i - 1]--;
                str[i] = '9';
            }
        }
        return stoi(str);                       //string转int
    }
};

但是这样在一些例子是错误的,比如100,从右往左比较0和是单调递增的,所以不变,返回90,但实际结果应该是99。
所以刚刚忽略了一点,就是如果某一位减1的话,后面的全部都是9。

正确版本

class Solution {
public:
    int monotoneIncreasingDigits(int n) {
        string str = std::to_string(n);         
        int index = str.size();                 //用来标志减1的位
        for(int i = str.size()-1; i > 0; i--){  //string对象的长度
            if(str[i - 1] > str[i]){
                str[i - 1]--;
                index = i-1;  
            }
        }
        for(int i = index + 1; i < str.size(); i++){
            str[i] = '9';
        }
        return stoi(str);                       //string转int
    }
};

涉及编程知识碎片

C++标准库中的数据类型转换函数

1、字符串转数字
stoi()
作用是将 n 进制的字符串转化为十进制,使用时包含头文件string
定义如下:

int stoi( const std::string& str, std::size_t* pos = nullptr, int base = 10 );

参数:
str - 待转换的字符
pos - 其取值可以是一个空字符,在这种情况下,pos未被使用;另外如果pos不是空指针,函数将pos的值设置为str中数字后面的第一个字符的位置。
base - 字符中数字的进制,默认为10进制,如果base取值为0,则进制由字符串中的格式决定。

返回值:
如果转换成功的话,stoi函数将会把转换后的得到数字以int类型返回。
如果字符串中没有数字的话,将会抛出"invalid_argument"的异常;
如果字符串中的数字转换后超过int的范围,将会抛出"out_of_range"的异常;
因此使用stoi函数的时候最好加入异常处理。
2、数字转字符串
std::to_string()

java代码

class Solution {
    public int monotoneIncreasingDigits(int n) {
        //数字转字符串
        String numstr = String.valueOf(n);
        //转数组
        String[] nums = numstr.split("");
        String result;
        int index = nums.length; //标记哪一位需要被减1
        //从后向前遍历比较
        for(int i = nums.length - 1; i > 0; i--){
            if(Integer.parseInt(nums[i]) < Integer.parseInt(nums[i-1])){
                index = i-1;
                nums[i -1] = String.valueOf(Integer.parseInt(nums[i - 1]) - 1);
            }
        }
        for(int i = index + 1; i < nums.length; i++){
            nums[i] = "9";
        }
        //拼接字符串
        result = String.join("",nums);
        //转数字
        return Integer.parseInt(result);
    }
}

涉及编程知识碎片

  1. String & int类型转换
  2. String的常用方法–分割、拼接
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值