打印从1到最大的n位数(DFS+回溯实现)

本文介绍了如何使用深度优先搜索(DFS)和回溯法来解决LeetCode上的一个问题,即输入n,打印从1到最大的n位十进制数。通过DFS递归构造数字,并在适当的时候回溯以保证正确结果。注意,解决方案将结果存储在List中,而非直接打印,且不考虑数组越界情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

输入数字 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);
            }
        }

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值