1. 问题描述:
我们定义「顺次数」为:每一位上的数字都比前一位上的数字大 1 的整数。
请你返回由 [low, high] 范围内所有顺次数组成的 有序 列表(从小到大排序)。
示例 1:
输出:low = 100, high = 300
输出:[123,234]
示例 2:
输出:low = 1000, high = 13000
输出:[1234,2345,3456,4567,5678,6789,12345]
提示:
10 <= low <= high <= 10^9
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sequential-digits
2. 思路分析:
① 题目还是很好理解的,我们只需要找出在这个范围内的所有这些满足条件的数字即可,一开始的时候计算出最小值与最大值数字对应的位数,并且在计算最低位数字的时候保存最小值的高位,计算这些最小值与最大值的位数使得形成的数字尽可能在这个范围之内
② 我们可以对保存的最小值的最高位开始计算,根据最小值的位数来形成顺序的数字,判断形成的数字是否在当前位数的最大值内,比如一位数字最大是9,两位数字最大是99以此类推,所以我们需要使用map来映射当前位数的最大值,因为是数字在10 ^ 9之内,所以计算到10位数字的最大值即可,假如在当前位数的最大值之内说明是符合要求的,假如超过了当前的位数,说明我们下一次形成的数字位数应该需要加一位,并且最高位是由1开始的,再循环中进行计算得到结果
③ 其实分析出来其中的过程,注意处理其中的细节即可
3. 代码如下:
class Solution {
public List<Integer> sequentialDigits(int low, int high) {
/*首先是需要求解出最小的数字与最大数字的位数是多少*/
int lowbits = 0, highbits = 0, l = low, h = high, start = 0;
while (l > 0){
start = l % 10;
l /= 10;
++lowbits;
}
while (h > 0){
h /= 10;
++highbits;
}
List<Integer> res = new ArrayList<>();
/*当前位数的最大值, 比如三位数字的最大值是999依次类推*/
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < 10; ++i){
map.put(i + 1, init(i + 1));
}
int t = start;
while (lowbits <= highbits){
/*得到当前的数字是多少*/
int n = check(start, lowbits);
if (n > high) return res;
if (n <= map.get(lowbits) && n >= low) res.add(n);
++start;
if (n == -1){
start = 1;
++lowbits;
}
}
return res;
}
private int init(int i) {
int res = 0, n = 0;
while (n < i){
res = res * 10 + 9;
++n;
}
return res;
}
private int check(int start, int lowbits) {
int res = 0, n = 0;
while (n < lowbits){
res = res * 10 + start;
/*防止n大于了9所以提前判断一下*/
if (start > 9) return -1;
++start;
++n;
}
return res;
}
}