# 单调递增的数字 给定一个非负整数`N`,找出小于或等于`N`的最大的整数,同时这个整数需要满足其各个位数上的数字是单调递增。当且仅当每个相邻位数上的数字`x`和`y`满足`x <= y`时,我们称这个整数是单调递增的。 ## 示例 ``` 输入: N = 10 输出: 9 ``` ``` 输入: N = 1234 输出: 1234 ``` ``` 输入: N = 332 输出: 299 ``` ## 题解 ```javascript /** * @param {number} N * @return {number} */ var monotoneIncreasingDigits = function(N) { let i = 1; let num = N; while(i*10 <= num){ // console.log(i, num); // 每次取出两位 let n = ~~(num / i) % 100; i = i * 10; if(~~(n/10) > n %10) num = ~~(num / i) * i - 1; // 例如 1332 第一次循环之后是 取整(1332 / 10) * 10 - 1 = 1330 - 1 = 1329 // 第二次循环就是 1300 - 1 = 1299 } return num; }; ``` ## 思路 整体思路就是将数字当作字符串,从尾到头逆向遍历一遍,每次比较两位,如果后一个位置上的数小于前一个位置上的数,那么就将前边的数减一,并将后边的所有位都变为`9`,例如当我们遍历到了`1323`中比较`32`的这个位置上,此时`3 > 2`符合条件,那么我们就将`3`减一并将其后的数都变作`9`,即将其变为`1299`,直到遍历到头即可。通常来说可以把数字作为字符串来遍历处理,上面的题解是使用纯数字的方式去做,首先定义`i`作为标记记录遍历到到的位置,之后定义`num`作为待处理的数字,定义循环只要能够继续取出两位数就继续循环,这是循环的终止条件,此外能够使用乘法的地方就尽量不要使用除法,在`js`中`int32`如果不能够整除则会自动转双精度`64`,所以在很多地方都需要强制转数值为`int32`,之后取出两位数,这里`~~`是使用位运算强制转了整型,在之后将`i * 10`定义到下一位,如果低一位上的值大于大于高一位上的值,那么就将数值在第`i`位以后的值都变成`0`,然后减`1`即可达到上述的将此位减`1`以及之后的数字都变为`9`,可以参考上边的示例,在循环结束后返回处理的数字即可。 ## 每日一题 ``` https://github.com/WindrunnerMax/EveryDay ``` ## 参考 ``` https://leetcode-cn.com/problems/monotone-increasing-digits/ ```