天王星算法强化班

天王星算法强化班

236.二叉树的最近公共祖先(middle

idea

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

code

class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        if root is None or root is p or root is q:
            return root
        left=self.lowestCommonAncestor(root.left,p,q)
        right=self.lowestCommonAncestor(root.right,p,q)
        if left and right:
            return root
        if left:
            return left
        if right:
            return right
        

235.二叉搜索树的最近公共祖先(middle

idea

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

code

class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        x=root.val
        if p.val<x and q.val<x:
            return self.lowestCommonAncestor(root.left,p,q)
        if p.val>x and q.val>x:
            return self.lowestCommonAncestor(root.right,p,q)
        return root

102.BFS

解法1

class Solution:
    def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        if root is None:return []
        ans=[]
        cur=[root]
        while cur:
            nxt=[]
            vals=[]
            for node in cur:
                vals.append(node.val)
                if node.left:nxt.append(node.left)
                if node.right:nxt.append(node.right)
            ans.append(vals)
            cur=nxt
        return ans

当前层有就加入,然后找孩子,加到没有为止

解法2

        if root is None:
            return []
        ans=[]
        q=deque([root])
        while q:
            vals=[]
            for _ in range(len(q)):
                node=q.popleft()
                vals.append(node.val)
                if node.left:q.append(node.left)
                if node.right:q.append(node.right)
            ans.append(vals)
        return ans

103.zigzag BFS

class Solution:
    def zigzagLevelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        if root is None:
            return []
        ans=[]
        q=deque([root])
        even=False
        while q:
            vals=[]
            for _ in range(len(q)):
                node=q.popleft()
                vals.append(node.val)
                if node.left:q.append(node.left)
                if node.right:q.append(node.right)
            ans.append(vals[::-1]if even else vals)
            even=not even
        return ans

513.树左下角

class Solution:
    def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
        q=deque([root])
        while q:
            node=q.popleft()
            if node.right:q.append(node.right)
            if node.left:q.append(node.left)
        return node.val

17.电话号码组合(回溯

idea

为什么不能用循环

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如何思考递归

把边界条件和非边界条件写对,剩下的交给数学归纳法

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

code

MAPPING=['','','abc','def','ghi','jkl','mno','pqrs','tuv','wxyz']
class Solution:
    def letterCombinations(self, digits: str) -> List[str]:
        n=len(digits)
        if n==0:return []
        path=['']*n
        ans=[]
        def dfs(i):
            if i==n:
                ans.append(''.join(path))
                return
            for c in MAPPING[int(digits[i])]:
                path[i]=c
                dfs(i+1)
        dfs(0)
        return ans

78.子集

idea

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

code

class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        n=len(nums)
        ans=[]
        path=[]
        def dfs(i):
            if i==n:
                ans.append(path.copy())#相当于它每一个内容都是path,一改全改
                return
            dfs(i+1)
            path.append(nums[i])
            dfs(i+1)
            path.pop()#恢复现场,因为前面的append是递归外操作
        dfs(0)
        return ans

不copy的结果

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

idea2

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

code

        n=len(nums)
        ans,path=[],[]
        def dfs(i):
            ans.append(path.copy())
            if i==n:return
            for j in range(i,n):
                path.append(nums[j])
                dfs(j+1)
                path.pop()
        dfs(0)
        return ans

131.分割回文串

idea

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

code

class Solution:
    def partition(self, s: str) -> List[List[str]]:
        n=len(s)
        ans,path=[],[]
        def dfs(i):
            if i==n:
                ans.append(path.copy())
                return

            for j in range(i,n):
                t=s[i:j+1]
                if t==t[::-1]:
                    path.append(t)
                    dfs(j+1)
                    path.pop()
        dfs(0)
        return ans

77.组合

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

class Solution:
    def combine(self, n: int, k: int) -> List[List[int]]:
        ans=[]
        path=[]
        def dfs(i):
            if i<k-len(path):return
            if len(path)==k:
                ans.append(path.copy())
                return
            for j in range(i,0,-1):
                path.append(j)
                dfs(j-1)
                path.pop()
        dfs(n)
        return ans
class Solution:
    def combine(self, n: int, k: int) -> List[List[int]]:
        ans=[]
        path=[]
        def dfs(i):
            d=k-len(path)
            # if i<k-len(path):return
            if len(path)==k:
                ans.append(path.copy())
                return
            for j in range(i,d-1,-1):#条件放到这里
                path.append(j)
                dfs(j-1)
                path.pop()
        dfs(n)
        return ans

216.组合总和3

idea

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

code

class Solution:
    def combinationSum3(self, k: int, n: int) -> List[List[int]]:
        ans,path=[],[]
        def dfs(i,t):
            d=k-len(path)#这里的d,k不要搞混   
            if t<0 or t>(2*i-d+1)*d/2:return
            if k==len(path):#注意这里是k
                ans.append(path.copy())
                return
            for j in range(i,d-1,-1):
                path.append(j)
                dfs(j-1,t-j)
                path.pop()  
        dfs(9,n)
        return ans

code2

        ans,path=[],[]
        def dfs(i,t):
            d=k-len(path)
            if t<0 or t>(i*2-d+1)*d/2:
                return
            if d==0:
                ans.append(path.copy())
                return
            if i>d:#不包含当前元素
                dfs(i-1,t)
            path.append(i)
            dfs(i-1,t-i)
            path.pop()
        dfs(9,n)
        return ans

22.括号生成

idea

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

code

class Solution:
    def generateParenthesis(self, n: int) -> List[str]:
        m=2*n
        ans=[]
        # path=['']*m
        path=[]
        def dfs(i,open):
            if i==m:
                ans.append(''.join(path))
                return#不要忘记return
            if open<n:
                # path[i]='('
                path.append('(')
                dfs(i+1,open+1)
                path.pop()#这里不用pop
            if i-open<open:
                # path[i]=')'
                path.append(')')
                dfs(i+1,open)
                path.pop()#这里不用pop
        dfs(0,0)
        return ans

关于是否要pop的问题,定长的数组不需要pop,pop会报错

46.全排列

idea

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

code

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        ans,path=[],[]
        k=len(nums)
        def dfs(i,s):
            if len(path)==k:
                ans.append(path.copy())
                return
            for x in s:
                path.append(x)
                dfs(i+1,s-{x})#每一次又开始从下标为0的数字开始pop,所以如果是list,会有一个remove的NoneType ERROR
                path.pop()
        dfs(0,set(nums))
        return ans

code2

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        ans,path=[],[]
        k=len(nums)
        on_path=[False]*k
        def dfs(i):
            if len(path)==k:
                ans.append(path.copy())
                return
            # for x in s:
            #     path.append(x)
            #     dfs(i+1,s-{x})
            #     path.pop()
            for j in range(k):
                if not on_path[j]:
                    path.append(nums[j])
                    on_path[j]=True
                    dfs(i+1)
                    on_path[j]=False
                    path.pop()
        dfs(0)
        return ans

code3

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        ans,path=[],[]
        k=len(nums)
        # on_path=[False]*k
        def dfs(i):
            if len(path)==k:
                ans.append(path.copy())
                return
            for j in range(k):
                if -10<=nums[j]<=10:
                    path.append(nums[j])
                    nums[j]+=21
                    dfs(i+1)
                    nums[j]-=21
                    path.pop()
        dfs(0)
        return ans

加上一个值当作bool条件

51.N皇后(困难

idea

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

code1

class Solution:
    def solveNQueens(self, n: int) -> List[List[str]]:
        ans=[]
        col=[0]*n

        def valid(r,c):
            for R in range(r):
                C=col[R]
                if r+c==R+C or r-c==R-C:
                    return False
            return True

        def dfs(r,s):
            if r==n:
                ans.append(['.'*c+'Q'+'.'*(n-1-c) for c in col])
                return
            for c in s:
                if valid(r,c):
                    col[r]=c
                    dfs(r+1,s-{c})
        dfs(0,set(range(n)))
        return ans

code2(all函数)

class Solution:
    def solveNQueens(self, n: int) -> List[List[str]]:
        ans=[]
        col=[0]*n

        def dfs(r,s):
            if r==n:
                ans.append(['.'*c+'Q'+'.'*(n-1-c) for c in col])
                return
            for c in s:
                if all(r+c != R+col[R] and r-c !=R-col[R] for R in range(r)):
                    col[r]=c
                    dfs(r+1,s-{c})
        dfs(0,set(range(n)))
        return ans

优化

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

code3

class Solution:
    def solveNQueens(self, n: int) -> List[List[str]]:
        ans=[]
        col=[0]*n
        on_path=[False]*n
        m=2*n-1
        diag1=[False]*m
        diag2=[False]*m
        def dfs(r):
            if r==n:
                ans.append(['.'*c+'Q'+'.'*(n-1-c) for c in col])
                return
            for c in range(n):
                if not on_path[c] and not diag1[r+c] and not diag2[r-c]:
                    col[r]=c
                    on_path[c]=diag1[r+c]=diag2[r-c]=True
                    dfs(r+1)
                    on_path[c]=diag1[r+c]=diag2[r-c]=False
        dfs(0)
        return ans

image-2024053020024937image-20240530200249378

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值