力扣剑指offer之打印从1到最大的n位数

输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。
示例 1:
输入: n = 1
输出: [1,2,3,4,5,6,7,8,9]

思路复现: 第一次看见本题,会感觉挺简单的,并且力扣给的标签也是简单,所以很容易直接下笔就写代码。这里只需要注意几个点:
1、给定一个数值n,你怎么得到最后一个n位数是多少呢?
我们可以这样思考:我们假定给的数值是2,那最后一个两位数就是99,它的下一位100不就是10的2次方吗??我们在尝试带入三,会发现确实如我们所想的,它的最大n位数就是10的n次方减1.
2、要注意0是不能输出的。所以应该避开0,从1开始记录。

class Solution {
    public int[] printNumbers(int n) {      
        int count = 10;
        // count = count**n;
        count = (int)Math.pow(10,n);
        int[] result = new int[count-1];
        for(int i = 0; i < count-1; i++){
            result[i] = i+1;
        }
        return result;
    }
}

还不错,成功通过了!!!然后很开心的打开讨论区,发现事情并没有想的那么简单!!!评论区有人提到了这道题还有一个版本要难,是因为考虑到大数的情况,要知道如果n是一个很大的数,比如是87,100,等等,那么int是不是就要越界了??那我们就应该考虑使用字符串来作为我们存储数字的单元了。

还好没直接关闭网站,去看了眼讨论区,要不然岂不是漏掉了重要信息??在知道了还有大数这一情况后,我们重新进行思考,还像上面那样肯定行不通了,因为int都放不下,还怎么for循环向int中放数值啊。那么我们就可以考虑如下几步:
1)、输入数值n,也就是说我们要返回1位数的所有值,2位数的所有值,一直到n位数的所有值。所以我们应该写个循环,每次往子函数中放入i,让它返回长度为i位数的所有值情况。
2)、下面开始考虑子函数实现,当我们传入数值i时,就是说现在长度为i让你给出长度为i的数值所有可能取值,,,,这是不是和我们的回溯条件很像?我们要使用回溯法的一个基本前提就是题目中出现求一共多少种,最多多少种,或者最少多少种这类字眼时,我们就要考虑回溯或者动规了。因此我们应该可以想到回溯的。就算你想不到,那么我们这时还可以考虑,对于长度为i的数字字符串,每隔位置能取的值就是0到9,除了最高位不能取0外。这是不是就和数独问题一样,那不还是回溯吗????每次取0到9一种,放入数值字符串然后递归,最后回溯。
3)、确定回溯后,我们开始考虑回溯三部曲:方法参数列表,终止条件,单个循环逻辑。
3.1)参数列表肯定有长度为多长的数值字符串n,以及存放数值字符串的容器StringBulider。这里不使用String,因为String内用final关键字修饰了,不能修改值,但是StringBuilder可以随意修改字符串数值。
3.2)当我们数值字符串的长度递归为0时,也就是说,长度为i的字符串数值遍历到最后一个位置了,就要将该字符串放入到一个列表中,进行保存,说明这个递归完成。
3.3)单层逻辑就是for循环,然后0-9,当字符串数值长度为0并且此时循环数值也是0时,要跳过,是因为第一个数值不能是0,不管你是几位数,第一个数值都不是0. 下面就是将该数值放入字符串数值,递归到长度i的数值字符串的下一位,即使用n-1. 最后就是删除这一位回溯。

public class Solution {

    List<String> res;
    public List<String> printNumbers(int n) {
        res = new ArrayList<>();
        for(int i = 1; i <= n ; i++){
            trackback(i, new StringBuilder());
        }
        return res;
    }
    public  void  trackback(int n, StringBuilder numString){
        if(n == 0) {
            res.add(numString.toString());
            return;
        }
        for(int i = 0; i <= 9; i++){
            if(i == 0 && numString.length() == 0) continue;
            numString.append(i);
            trackback(n - 1, numString);
            numString.delete(numString.length() - 1, numString.length());
        }
    }
}

如果有没看明白的,可以评论区讨论!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值