题目描述
输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999
//Math.pow(double d1,double d2)注意强制转换为int
int count = (int)Math.pow(10,n);
不推荐,不是大数问题。
class Solution {
public int[] printNumbers(int n) {
int count = (int)Math.pow(10,n);
int[] ans = new int[count-1];
for(int i=0;i<count-1;i++){
ans[i] = i+1;
}
return ans;
}
}
这道题本意是大数问题,大数问题要用String类型来解决。
观察可知,生成的列表实际上是 n 位 0 - 9 的 全排列 ,因此可避开进位操作,通过递归生成数字的 String 列表。
class Solution {
StringBuilder res;
int count = 0, n;
char[] num, loop = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
public String printNumbers(int n) {
this.n = n;
res = new StringBuilder(); // 数字字符串集
num = new char[n]; // 定义长度为 n 的字符列表
dfs(0); // 开启全排列递归
res.deleteCharAt(res.length() - 1); // 删除最后多余的逗号
return res.toString(); // 转化为字符串并返回
}
void dfs(int x) {
if(x == n) { // 终止条件:已固定完所有位
res.append(String.valueOf(num) + ","); // 拼接 num 并添加至 res 尾部,使用逗号隔开
return;
}
for(char i : loop) { // 遍历 ‘0‘ - ’9‘
num[x] = i; // 固定第 x 位为 i
dfs(x + 1); // 开启固定第 x + 1 位
}
}
}
输出结果如下
输入:n = 1
输出:"0,1,2,3,4,5,6,7,8,9"
输入:n = 2
输出:"00,01,02,...,10,11,12,...,97,98,99"
输入:n = 3
输出:"000,001,002,...,100,101,102,...,997,998,999"
1.需要去除开头多余0。
1.可以采用 Integer.parseInt();
2.可以通过一个 start标识位来判断需要去除0的个数,看下面代码说明。
2.从1开始输出。
只需要判断是不是为0,即可。
class Solution {
StringBuilder res;
int nine = 0, count = 0, start, n;
char[] num, loop = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
public String printNumbers(int n) {
this.n = n;
res = new StringBuilder();
num = new char[n];
//初始值为n-1,代表要去除前n-1个0,类似001,002,003,004需要去除前面的0.
start = n - 1;
dfs(0);
res.deleteCharAt(res.length() - 1);
return res.toString();
}
void dfs(int x) {
if(x == n) {
String s = String.valueOf(num).substring(start);
if(!s.equals("0")) res.append(s + ",");
//类似99,999,等这种,说明进入了3位数和4位数,所以start要-1;
if(n - start == nine) start--;
return;
}
for(char i : loop) {
//判断有几个nine值,类似99,999等。
if(i == '9') nine++;
num[x] = i;
dfs(x + 1);
}
//回溯算法要进行nine--;
nine--;
}
}
转换为int[],且利用Integer.parseint();
class Solution {
char[] num;
int[] ans;
int count = 0,n;
public int[] printNumbers(int n) {
this.n = n;
num = new char[n];
ans = new int[(int) (Math.pow(10, n) - 1)];
dfs(0);
return ans;
}
private void dfs(int n) {
if (n == this.n) {
String tmp = String.valueOf(num);
int curNum = Integer.parseInt(tmp);
if (curNum!=0) ans[count++] = curNum;
return;
}
for (char i = '0'; i <= '9'; i++) {
num[n] = i;
dfs(n + 1);
}
}
}
另一种思想
1.当num的下标index是0时,则loop从下标1开始进行全排列
2. 当num的下标index非0时,则loop从下标0开始进行全排列
public class Solution {
char[] num, loop = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
StringBuilder sb = new StringBuilder();
public String printNumber(int len){
num = new char[len];
for(int i = 1;i<=len;i++){
dfs(0,i);
}
return sb.deleteCharAt(sb.length()-1).toString();
}
public void dfs(int index,int len){
if(index == len){
sb.append(new String(num)+",");
return;
}
int start = 0;
//若从0作为起点:if(index == 0 && len>1)
//若从1作为起点
if(index == 0){
start = 1;
}else{
start = 0;
}
for(int i=start;i<10;i++){
num[index] = loop[i];
dfs(index+1,len);
}
}
}