class Solution:
def getPermutation(self, n: int, k: int) -> str:
# time O(N^2) space O(N)
# edge case n=0
if n == 0:
return ""
used = [False for _ in range(n+1)]
path = []
# cache factorial number
factorial = [1 for _ in range(n+1)]
for i in range(2,n+1):
factorial[i] = factorial[i-1]*i
def dfs(n,k,idx,path):
if idx == n :
return
# start with lowest number at highest position, check if following numbers' permunation bigger than k, if yes => means kth number exists in the remaining permutation.
#keep insert current smallest number into path ;
# if no, means smallest number shouldn't be at the highest position, i += 1, skip permutation starting with least highest number by k -= cnt
cnt = factorial[n-1-idx]
for i in range(1,n+1):
if used[i]:
continue
if cnt < k :
k-=cnt
continue
path.append(i)
used[i] = True
dfs(n,k,idx+1,path) # here can't use path+[i] since it's not really backtracking(taking back number i )
return
dfs(n,k,0,path)
# convert path array into string
return ''.join([str(num) for num in path])