1. 问题描述:
给定一个整数 n, 返回从 1 到 n 的字典顺序。
例如,
给定 n =13,返回 [1,10,11,12,13,2,3,4,5,6,7,8,9] 。
请尽可能的优化算法的时间复杂度和空间复杂度。 输入的数据 n 小于等于 5,000,000。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/lexicographical-numbers
2. 思路分析:
分析题目可以知道我们需要使得字典序是最小的,类似于字符串的字典序排序,所以我们想到使用Trie树来解决,Trie树可以维护字符串中的字典序,并且在遍历Trie树的时候按照字典序大小进行遍历那么对应的遍历顺序得到的就是按照字典序排序的字符串,基于Trie树的思想我们也可以使用dfs遍历来解决,因为这里的数字都是连续的所以这里不用将所有数字都插入到Trie树中我们其实可以模拟这棵树是存在的然后dfs遍历即可,我们可以枚举每一个首位,这样可以避免首位是0的情况,然后dfs,只要当前的数字cur小于等于n说明是满足条件的,加入到res列表中,然后继续往下递归,往下递归的时候数字是比上一个数字多一位的,相当是遍历Trie树找到某一个单词的过程(这一点好巧妙),否则return到上一层。
3. 代码如下:
from typing import List
class Solution:
def dfs(self, cur: int, n: int, res: List[int]):
if cur <= n:
res.append(cur)
else:
return
# 相当于是在Trie树中找到某一个单词
for i in range(0, 10):
self.dfs(cur * 10 + i, n, res)
# 按照Trie树的思想进行dfs遍历
def lexicalOrder(self, n: int) -> List[int]:
res = list()
# 枚举首位即可避免第一位为0的情况
for i in range(1, 10):
self.dfs(i, n, res)
return res