給出集合[1,2,3,…,n]
,其所有元素共有 n! 種排列。
按大小順序列出所有排列情況,並一一標記,當 n = 3 時, 所有排列如下:
"123"
"132"
"213"
"231"
"312"
"321"
給定 n 和 k,返回第 k 個排列。
說明:
示例 1:
輸入: n = 3, k = 3
輸出: "213"
示例 2:
輸入: n = 4, k = 9
輸出: "2314"
思路:
每次迴圈根據k的大小可以確定第一位數,
舉例,設n = 3, k = 1, 此時第一位數隻可能是1, 2, 3,而且一共有3! = 6種結果,所以每個數開頭對應兩種結果
當k = 1或2時,對應的第一位就是1,
當k = 3或4時,對應2,
當k = 5或6時,對應3,
以此類推,可以不斷確定第一位的結果。
import math
class solution(object):
def getpermutation(self, n, k):
""":type n: int
:type k: int
:rtype: str
"""digit = [i for i in range(1, n + 1)] #生成1 ~ n的列表
res = ""
while n > 0:
tmp = math.factorial(n - 1) #計算一共有多少種組合
idx = (k - 1) / tmp #由k在tmp中佔的比例來確定第一位的數字
k -= idx * tmp #第一位確定之後,重新整理k
res += str(digit[idx])
digit.pop(idx)
n -= 1
return res
或者遞迴:
class solution(object):
def getpermutation(self, n, k):
""":type n: int
:type k: int
:rtype: str
"""fac = [1]
for i in range(2, n + 1):
digits = [i for i in range(1, n + 1)]
self.res = ""
def dfs(left_digit, tmp, kk):
if left_digit == 0:
self.res = tmp[:]
return
for digit in digits:
kk -= fac[left_digit - 2]
if kk <= 0:
kk += fac[left_digit - 2]
fac.pop()
digits.remove(digit)
dfs(left_digit - 1, tmp + str(digit), kk)
break
dfs(n, "", k)
return self.res
LeetCode Python 6 Z 字形變換
將乙個給定字串根據給定的行數,以從上往下 從左到右進行 z 字形排列。比如輸入字串為 leetcodeishiring 行數為 3 時,排列如下 l c i r e t o e s i i g e d h n 之後,你的輸出需要從左往右逐行讀取,產生出乙個新的字串,比如 lciretoesiiged...
LeetCode python 6 Z 字形變換
將乙個給定字串根據給定的行數,以從上往下 從左到右進行 z 字形排列。比如輸入字串為 leetcodeishiring 行數為 3 時,排列如下 l c i r e t o e s i i g e d h n之後,你的輸出需要從左往右逐行讀取,產生出乙個新的字串,比如 lciretoesiigedh...
LeetCode Python 打家劫舍I
你是乙個專業的小偷,計畫偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。給定乙個代表每個房屋存放金額的非負整數陣列,計算你在不觸動警報裝置的情況下,能夠偷竊到的最高金額。示例 1 輸入 1...