2021-12-10 每日打卡:腾讯精选50题
写在前面
“这些事儿在熟练之后,也许就像喝口水一样平淡,但却能给初学者带来巨大的快乐,我一直觉得,能否始终保持如初学者般的热情、专注,决定了在做某件事时能走多远,能做多好。” 该系列文章由python编写,遵循LeetBook 列表/腾讯的刷题顺序,所有代码已通过。每日3道,随缘剖析,希望风雨无阻,作为勉励自己坚持刷题的记录。
22. 括号生成
- 可以在当前括号的中间or旁边加,直接使用动态规划:
'''
动态规划:
dp[i]表示i组括号的所有有效组合
dp[i] = "(dp[p]的所有有效组合)+【dp[q]的组合】",其中 1 + p + q = i , p从0遍历到i-1, q则相应从i-1到0
'''
class Solution:
def generateParenthesis(self, n: int) -> List[str]:
dp = [[] for _ in range(n+1)] # dp[i]存放i组括号的所有有效组合
dp[0] = [""] # 初始化dp[0]
for i in range(1, n+1): # 计算dp[i]
for p in range(i): # 遍历p
l1 = dp[p] # 得到dp[p]的所有有效组合
l2 = dp[i-1-p] # 得到dp[q]的所有有效组合
for k1 in l1:
for k2 in l2:
dp[i].append("({0}){1}".format(k1, k2))
return dp[n]
- 递归(动归)的另一种写法:
class Solution:
@lru_cache(None)
def generateParenthesis(self, n: int) -> List[str]:
if n == 0:
return ['']
ans = []
for c in range(n):
for left in self.generateParenthesis(c):
for right in self.generateParenthesis(n-1-c):
ans.append('({}){}'.format(left, right))
return ans
46. 全排列
- 上次百度校园还考到了,库函数还是需要记一下滴:
import itertools
def permute(self, nums: List[int]) -> List[List[int]]:
return list(itertools.permutations(nums))
这个库函数简直很牛,看看其它功能吧:Python itertools模块详解
- 老实回溯法:
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
self.res = []
def backtrack(nums, tmp):
if not nums:
self.res.append(tmp)
return
for i in range(len(nums)):
backtrack(nums[:i] + nums[i+1:], tmp + [nums[i]])
backtrack(nums, [])
return self.res
78. 子集
- 回溯的关键是传递路径,所以你的小函数中一定有一个参数是当前路径,是以“复制”的形式传递的所以每次都可以用相同的路径!
class Solution:
def subsets(self, nums: List[int]) -> List[List[int]]:
self.res = [[]]
def backtrack(nums, tmp):
# 使用for的话可以不用判断return
for i in range(len(nums)):
tmp_ = tmp + [nums[i]]
backtrack(nums[i+1:], tmp_)
self.res.append(tmp_)
backtrack(nums, [])
return self.res
- 还有更牛的:
class Solution:
def subsets(self, nums: List[int]) -> List[List[int]]:
res=[[]]
n=len(nums)
for i in range(n):
for j in range(len(res)):
res.append(res[j]+[nums[i]])
return res
89. 格雷编码【第一遍未做出】
- 找规律,镜像翻转法:
class Solution:
def grayCode(self, n: int) -> List[int]:
res, head = [0], 1
for i in range(n):
for j in range(len(res) - 1, -1, -1):
res.append(head + res[j])
head <<= 1
return res
- 公式法(记住):第n个格雷码对应的公式为
G(n) = n xor (n >> 1)
class Solution:
def grayCode(self, n: int) -> List[int]:
res, head = [], 1
for i in range(1<<n):
res.append(i^(i>>1))
return res