题目
输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。
示例 1:
输入: n = 1
输出: [1,2,3,4,5,6,7,8,9]
说明:
1、用返回一个整数列表来代替打印;
2、n 为正整数。
思路
1、数字的每一位都可以由0 ~ 9的数字组成;(最高位不能为0)
2、所以我们可以使用深度优先搜索算法(DFS)来实现数字的构造;
3、深度优先搜索(DFS):可理解为朝着某个方向一直递归下去,直到最后一个节点;
4、回溯是保证StringBuilder保存的数字是正确的,为空时不需要回缩。(比如当n = 2时,如果没有回溯,则StringBuilder保存的是所有数字连接在一起的字符串,则为“12345678910111213…”,而不是单个数字“1,2,3…”)
注意
1、因为原题返回的结果为int数组,所以这里没有考虑越界的情况,直接保存在List集合中;
2、如果这里需要考虑越界的情况,可以保存在List集合中,然后再进行相应的操作。
实现
class Solution {
// 保存结果的集合
List<Integer> resultList = new ArrayList<>();
// 数位可能出现的值
char[] nums = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
public int[] printNumbers(int n) {
// dfs构造所有数
dfs(0, n, new StringBuilder());
// 将List集合转化为符合要求的int数组
int[] result = new int[resultList.size()];
for (int i = 0; i < resultList.size(); i ++) {
result[i] = resultList.get(i);
}
// 返回结果
return result;
}
/**
* dfs
*
* @param place 遍历的数位(0表示最高为,1表示次高位,以此类推)
* @param n 总位数
* @param numStr 保存对应数字的StringBuilder
*/
public void dfs(int place, int n, StringBuilder numStr) {
// 结束条件,遍历完每一位
if (place == n) {
// 将符合要求的添加到结果集合中(排除numstr为空的情况,当每一位都为0时,numstr为空)
if (numStr.length() != 0) {
resultList.add(Integer.valueOf(numStr.toString()));
}
return;
}
// 循环构造每一位的数字
for(char num : nums) {
// 最高位不是’0‘,才更新该数字(最高位为0不符合要求,比如01)
if (numStr.length() != 0 || num != '0') {
numStr.append(num);
}
// 递归构造下一位
dfs(place + 1, n, numStr);
// 回溯(numStr存在的情况才回溯,为空不需要回溯)
if (numStr.length() != 0) {
numStr.deleteCharAt(numStr.length() - 1);
}
}
}
}