贪心——738.单调递增的数字
给定一个非负整数 N,找出小于或等于 N 的最大的整数,同时这个整数需要满足其各个位数上的数字是单调递增。
(当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,我们称这个整数是单调递增的。)
示例 1:
- 输入: N = 10
- 输出: 9
示例 2:
- 输入: N = 1234
- 输出: 1234
示例 3:
- 输入: N = 332
- 输出: 299
说明: N 是在 [0, 10^9] 范围内的一个整数。
首先把数字n按位,从小到大(从后往前)处理成list:
1 List<Integer> list = new ArrayList<>(); 2 while (n >= 1) { 3 list.add(n % 10); 4 n /= 10; 5 }
将当前的数n处理成比n小的最大“递增数“,关键就在于位数上的递增。
从n的每一位数从高到低来说,如果当前要比较的数字[index]和遍历到的数字[i]:
- 大于:当前数字符合递增要求,
index = i--;
- 等于:当前数字无法判断,需要遍历下一位数:
i--;
- 小于:
- 当前位数够减一:直接减
- 当前位数不够减:向前借位直到
- 够减一
- 第一位数(第一位数 >= 1,肯定够)
代码如下:
1 class Solution { 2 public int monotoneIncreasingDigits(int n) { 3 List<Integer> list = new ArrayList<>(); 4 while (n >= 1) { 5 list.add(n % 10); 6 n /= 10; 7 } 8 //count == 位数,index == 判断的位数 9 int count = list.size(), index = count - 1, i = count - 2; 10 while (i >= 0) { 11 if (list.get(i) > list.get(index)) { 12 index = i--; 13 } else if (list.get(i) < list.get(index)) { 14 //向前借位(可向前0位),直到当前数字够-1 or 到了第一位(借位到了第一位,第一位数字必定 >= 1,肯定够) 15 while (list.get(index) == 0 && index > 0) { 16 --index; 17 } 18 //当前位数-1 19 list.set(index, list.get(index)-1); 20 //从-1位数的后一位开始,每一位数都是9 21 --index; 22 while (index >= 0) { 23 list.set(index--, 9); 24 } 25 break; 26 } else { 27 --i; 28 } 29 } 30 31 int result = 0, base = 1; 32 i = 0; 33 while (i < count) { 34 result += list.get(i++) * base; 35 base *= 10; 36 } 37 return result; 38 } 39 }
时间:O(n)
空间:O(1)(除了返回值无须额外空间)