算法思路:
- 定义res数组存储结果,nine、count和start用于控制递归过程。
- 将n赋值给类变量,初始化res和num数组。
- start表示num中有效位数的起始位置。
- 调用dfs开始递归。
- 递归终止条件:xn,此时得到一个数字,判断是否去除前导0后加入res。如果ninen-start,出现了"9",需回溯。
- 遍历’0’到’9’,递归调用dfs,并修改nine和num[]。
- 回溯,nine减1。
- dfs递归结束,返回res数组。
- 本题考察递归和回溯,需要理解程序的递归流程。
class Solution {
int[] res; //存储计算结果的数组
int nine = 0, count = 0, start, n; //nine记录"9"的个数,count用于记录res的索引
char[] num, loop = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
public int[] printNumbers(int n) {
this.n = n; //将传入的n赋值给类变量n
res = new int[(int)Math.pow(10, n) - 1]; //初始化res数组
num = new char[n]; //num存储每次递归得到的数字
start = n - 1; //start用于标记num的有效位数的起始位置
dfs(0); //开始递归
return res;
}
void dfs(int x) {
//递归终止条件:x == n表示已经递归到最高位
if(x == n) {
//num有效位数起始位置之后的数字转为字符串并去除前导0
String s = String.valueOf(num).substring(start);
//如果不等于"0",将其添加到res并递增res索引count
if(!s.equals("0")) res[count++] = Integer.parseInt(s);
//如果此时nine等于最高位到start之间的位数,说明出现了"9",需回溯
if(n - start == nine) start--;
return;
}
//遍历'0'到'9',递归调用dfs
for(char i : loop) {
//如果是'9',nine加1
if(i == '9') nine++;
//当前位设置为i,继续递归下一位
num[x] = i;
dfs(x + 1);
}
//回溯,nine减1
nine--;
}
}
算法思路:
- 初始化weishu=10^n-1,计算能打印的最大数字。
- 初始化数组re,长度为weishu。
- 给re数组赋值,从1到weishu。
- 返回re数组。
该算法时间复杂度为O(n),空间复杂度为O(1)。
class Solution {
public int[] printNumbers(int n) {
//初始化weishu,用于计算能够组成的最大数字,weishu=10^n-1
int weishu = (int)Math.pow(10,n) - 1;
//初始化数组re,长度为weishu
int[] re = new int[weishu];
//给re数组赋值,从1到weishu
for (int i = 0;i < weishu; i++){
re[i] = i + 1;
}
//返回re数组
return re;
}
}