1291 顺次数(map、分析)

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;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值