剑指 Offer 17. 打印从1到最大的n位数
全排列,DFS,回溯
题目链接-来源:力扣(LeetCode)
输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。
示例 1:
输入: n = 1
输出: [1,2,3,4,5,6,7,8,9]
思路:
鉴于LeetCode中本题只需输出int,可知n不存在越界可能。只要实现一个关于整数的n次幂的计算方法,对任意n调用 pow(10, n) ,再从1开始循环打印即可。
拓展:
当然对于更广泛的使用场景而言(也是本题真正的考点),我们要考虑大数越界的情况,即输入的n可能是一个 long 型大数,甚至是一个类似 __uint128_t 的大数。那么我们需要借助不限长度的字符串,帮助我们实现数字的打印。
于是问题转化成,「输出n位 ‘0’~’9’数字的全排列」,我们可以用回溯算法+ DFS 来解决此类字符串的拼接、遍历问题。
对于函数的主体 DFS(n),算法结构如下:
- 对于每一位数字,我们在字符串中加上它,然后继续对其下一位使用 DFS(n - 1),待返回后,「恢复现场」,将这位数字删除,进入下一个循环(依次遍历’0’ ~ ‘9’)。
- 如果到达末位(n = 1),我们要输出拼接好的数字,然后返回。
实操中,你可以从低位向高位遍历,也可以从高位向低位遍历(我采用后者)。但无论哪种方向,都有一个问题,遍历过程中高位会出现不该有的 ‘0’ (如 09,005,0003等)。当然对于本题,由于返回的是int[]类型,只需调用 parseInt() 不存在这种麻烦,如果题目要求我们按 String 返回,就需要额外考虑 ‘0’ 了,当然代码也不负责,只是稍显繁琐。我的实现中考虑了这种情况。
时间复杂度:O(10^n)
空间复杂度:O(10^n)
实现:
1 | class Solution { |
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.