天王星算法强化班
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