问题扩展:

本题应当考察的是大数问题,当 n较大时,end会超出 int32 整型的范围,超出取值范围的数字无法正常存储。

大数问题的解决需要考虑三个方面的重点:

  • 1 . 表示大数的变量类型

无论是 short / int / long … 任意变量类型,数字的取值范围都是有限的。因此,大数的表示应用字符串 String 类型。

  • 2 .数字进位

​ 比如说从 9进一位到10 ,从99进1位到100.需要考虑如何操作。

  • 3 .递归的全排列

​ 基于分治的思想,当 n=2时可以分为各位和十位。先固定个位,然后十位依次从 0到9设置。

过程重点:

  • 设置一个char 类型的数组来存储递归过程中某一位的数字,当当前待设置的位置等于题目给出的位数时说明所有位置的数字已经排列完毕,那么生成字符串凭借在结果后面。

  • 对于数字0的处理,开始没有考虑这一点,结果中会出现 01 、001 、0001 这种情况,这不符合题意。那么如何去除多余的0。举例可以发现,当 n=2时,当 结果为 01 时我们需要 String.subString(1);当结果为 001 时我们需要 subString(2)。而从 9进一位到 10时截取的位置发生了改变,从1变化为了 0 ,可以得出 如果等式 nine + start = n 成立时(start 为截取的位置、 nine 为9的个数),需要将 start–

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
  /**
* 大数问题打印----输出 从1到最大n位数的所有数
* @param n
* @return
*/
StringBuilder res = new StringBuilder();
int n,nine,start;
char []num,loop= {'0','1','2','3','4','5','6','7','8','9'};
public String printNumber(int n) {
this.n=n;
start = n-1;
nine = 0;
num = new char[n];
dfs(0);
System.out.println(res.toString());
return res.toString();
}

public void dfs(int x) {
if(x == n) {
//最后遍历完了所有的位数
String s = new String(num).substring(start);
res.append(s).append(",");
if(start+nine==n)
start--;
return;
}
//没有遍历完就存储当前位到num数组中
for(char ch:loop) {
if(ch=='9')
nine++;
num[x] = ch;
dfs(x+1);
}
nine--; //注意这里的nine 为9的个数,每次递归完成后必须减1
}

结果打印: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23....