剑指 Offer 17. 打印从1到最大的n位数

128 阅读2分钟

题目描述

输入数字 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: 暴力破解法,

我们根据n 可以求出当前需要输出的最大值是 (10^n-1), 然后遍历即可
时间复杂度: O(10^N)

示例代码1:

def printNumbers(n: int) -> [int]:
    res = []
    for i in range(1, 10 ** n):
        res.append(i)
    return res
    
#可以用python的 list 构造方法来简化这个代码
def printNumbers(n: int) -> [int]:
    return list(range(1, 10 ** n)) 

解题思路2: 大数全排列(递归回溯)

我们可以根据计算全排列的方式, 看做 n位的全排列, 然后每个排列就是一个结果
时间复杂度: O(10^N)

如图: 大数全排列 如果 n=2, 我们一共进行2次 遍历, 第一次进行 n=1, 第二次进行 n=2
对于每次遍历, 我们都进行 1-9的循环
对于每次循环, 我们进行 n层递归, 每次递归都 拼接 0-9

示例代码2:

def printNumbers(n: int) -> [int]:
    def dfs(index, digit, nums):
        if index == digit:
            res.append(int("".join(nums)))  # 将字符串拼接成数字
            return
        for i in range(0, 10):
            nums.append(str(i))  # 加入当前排列
            dfs(index + 1, digit, nums)  # 进行n层递归
            nums.pop()  # 恢复数据

    res = []  # 存放最终结果
    nums = []  # 临时存放全排列

    for digit in range(1, n + 1):  # 进行digit次遍历
        for i in range(1, 10):  # 每一层进行 1, 9的循环
            nums = [str(i)] # 初始化当前循环初始值
            dfs(1, digit, nums)
    return res

递归的效率依然是最低.......

100ms是递归, 48ms是2种写法的循环