这道题可算是写了一下午,思路错误写半天还超时,思路正确1min写出来!!!
所以啊,好的思路胜过一切,做题前还是多想想办法。
首先给出我写了半天还超时的代码叭,留作纪念:
主要就是遍历1到n,然后维护一个列表,每次将数字插入到列表中的正确位置,这样一来时间复杂度可就高了去了
class Solution:
def lexicalOrder(self, n):
ans=[1]
def insert_(s,j):
s=str(s)
j=str(j)
if len(s)>=len(j):
for i in range(len(j)):
if j[i]>s[i]:
return True
else:
return False
if len(s)<len(j):
for i in range(len(s)):
if j[i]>s[i]:
return True
if j[i]<s[i]:
return False
else:
return True
def help(temp,num):
for i in range(len(temp)):
if insert_(temp[i],num): # 找到第一个比num小的元素进行插入到后面
if i!=len(temp)-1 and not insert_(temp[i+1],num):
temp.insert(i+1,num)
break
if i==len(temp)-1:
temp.insert(i + 1, num)
break
for i in range(n-1):
help(ans,i+2)
return ans
然后呢,就超时了,看了答案,发现了一张神奇的图
这不就是先序遍历嘛,然后当数字大于n时就return就好了,代码如下:
class Solution:
def lexicalOrder(self, n):
ans=[]
def dfs(ans,i):
if i>n:
return
ans.append(i)
for j in range(0,10):
dfs(ans,i*10+j)
for i in range(1,10):
dfs(ans,i)
return ans
能想到这张图可就好做多了。
为了实现时间复杂度为 O(n) 且使用 O(1) 额外空间的算法的要求,将dfs改写成如下形式,
class Solution:
def lexicalOrder(self, n: int) -> List[int]:
ans = []
num = 1
while len(ans) < n:
while num <= n: # 不断进入下一层
ans.append(num)
num *= 10
while num % 10 == 9 or num > n: # 不断返回上一层
num //= 10
num += 1 # 遍历该层下一个数
return ans
能想到这种解法真的是超牛的喔,需要继续学习,不断努力!!! 2022/2/26