一、学习视频
如何灵活运用递归?【基础算法精讲 10】_哔哩哔哩_bilibili
二、跟练代码
1. 100. 相同的树
递归
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
# 递归
if p is None and q is None:
return True
elif p is None or q is None:
return False
left = self.isSameTree(p.left,q.left)
right = self.isSameTree(p.right,q.right)
return left and right and p.val == q.val
学习一下灵神的写法,来自视频。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
# 递归
# if p is None and q is None:
# return True
# elif p is None or q is None:
# return False
if p is None or q is None:
return p is q
left = self.isSameTree(p.left,q.left)
right = self.isSameTree(p.right,q.right)
return left and right and p.val == q.val
递归
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isSymmetric(self, root: Optional[TreeNode]) -> bool:
# 递归
# 含有根节点
# 判断根节点的左右两子树
def f(left: Optional[TreeNode], right: Optional[TreeNode]) -> bool:
if left is None or right is None:
return left is right
return f(left.left,right.right) and f(left.right,right.left) and left.val == right.val
# #根节点为空时是满足的,此处含根节点可以省去
# if root is None:
# return True
return f(root.left,root.right)
递归。不会,来自视频代码。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isBalanced(self, root: Optional[TreeNode]) -> bool:
# 递归
# 计算高度,非负数
# 用-1表示不是平衡二叉树
def f(node) -> int:
if node is None:
return 0
# left_h = f(node.left)
# right_h = f(node.right)
# if left_h == -1 or right_h == -1 or abs(left_h - right_h) > 1:
# return -1
# return max(left_h, right_h) + 1
# 少递归一些
left_h = f(node.left)
if left_h == -1:
return -1
right_h = f(node.right)
if right_h == -1 or abs(left_h - right_h) > 1:
return -1
return max(left_h, right_h) + 1
return f(root) != -1
递归
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
# 递归
# 先右后左遍历,当高度大于minHeight时,才会露出来
ans = []
minHeight = 0
def f(node,height):
nonlocal minHeight
if node is None:
return
if height > minHeight:
ans.append(node.val)
minHeight += 1
right = f(node.right,height + 1)
left = f(node.left,height + 1)
return
f(root,1)
return ans
三、课后作业
递归
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
# 递归
if root is None:
return None
left = self.invertTree(root.left) #左子树
right = self.invertTree(root.right) #右子树
root.left = right #左右互换
root.right = left
return root
不会,全都来自灵神题解(. - 力扣(LeetCode)),学习学习。
(1)递
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def maxAncestorDiff(self, root: Optional[TreeNode]) -> int:
# 递
v = -1
def f(node,mx,mn):
nonlocal v
if node is None:
return #不一定要有返回值
mx = max(mx,node.val)
mn = min(mn,node.val)
v = max(v, node.val - mn, mx - node.val) #更新
f(node.left,mx,mn)
f(node.right,mx,mn)
f(root, root.val, root.val) #根节点存在
return v
(2)递的优化
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def maxAncestorDiff(self, root: Optional[TreeNode]) -> int:
# 递的优化
v = -1
def f(node,mx,mn):
if node is None:
nonlocal v
v = max(v, mx - mn) #到终点更新
return
mx = max(mx,node.val)
mn = min(mn,node.val)
f(node.left,mx,mn)
f(node.right,mx,mn)
f(root, root.val, root.val) #根节点存在
return v
(3)归
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def maxAncestorDiff(self, root: Optional[TreeNode]) -> int:
# 归
v = -1
def f(node):
if node is None:
return inf, -inf # min max
mn = mx = node.val
lmin, lmax = f(node.left)
rmin, rmax = f(node.right)
mn = min(mn, lmin, rmin)
mx = max(mx, lmax, rmax)
nonlocal v
# 每一次都更新v
v = max(v, node.val - mn, mx - node.val)
return mn, mx
f(root)
return v
递可以不用每次都更新v值,因为从上到下能确保最大小值就是该条路径的,而没有受其他路径影响;而归每次都需更新v值,一个节点有左右两边两条路径到达。
(1)递归。参考官方题解(. - 力扣(LeetCode))。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def sufficientSubset(self, root: Optional[TreeNode], limit: int) -> Optional[TreeNode]:
# 递归
# 递总值 归是否删除(False删)
def f(node, s):
if node is None:
return False
if node.left is None and node.right is None:
return s + node.val >= limit
left = f(node.left, s + node.val)
right = f(node.right, s + node.val)
if not left:
node.left = None
if not right:
node.right = None
return left or right
rootBool = f(root, 0)
return root if rootBool else None
注意删除节点不能本节点直接删除,要在上一节点删除(删除联系)。
(2)递归(调用自身写法)。参考灵神题解(. - 力扣(LeetCode))。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def sufficientSubset(self, root: Optional[TreeNode], limit: int) -> Optional[TreeNode]:
# 递归(调用自身写法)
# 通过更改limit实现求和的作用
if root is None:
return None
if root.left is root.right: #为叶子节点
return root if root.val >= limit else None
root.left = self.sufficientSubset(root.left, limit - root.val)
root.right = self.sufficientSubset(root.right, limit - root.val)
return root if root.left or root.right else None
可以通过 root.left is root.right 来判断是不是叶子节点。
(1)递归+非局部变量
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def longestZigZag(self, root: Optional[TreeNode]) -> int:
# 递归+非局部变量
# 递标签,归和值
ans = 0
def f(node: Optional[TreeNode], flag: str) -> int:
nonlocal ans
if node is None:
return 0
left = f(node.left, 'left')
right = f(node.right, 'right')
if flag == 'left': #该节点是父节点的左节点,下一步该右节点
ans = max(ans, left) #更新左节点和值
return right+1 #继续归右节点和值
else:
ans = max(ans, right)
return left+1
# 更新最终返回值
ans = max(f(root.left,"left"),f(root.right,"right"),ans)
return ans
(2)递归+非局部变量2。来自题解(. - 力扣(LeetCode)),很妙很妙。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def longestZigZag(self, root: Optional[TreeNode]) -> int:
# 递归+非局部变量2
ans = 0
def f(node, l, r): #递左右最大值
nonlocal ans
ans = max(ans, l, r)
if node.left:
f(node.left, r+1, 0)
if node.right:
f(node.right, 0, l+1)
f(root, 0, 0)
return ans
完
感谢你看到这里!一起加油吧!