2021-12-10 每日打卡:腾讯精选50题

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值