2024.(3.30和4.1)力扣刷题记录-二叉树学习记录2

本文详细介绍了递归在处理二叉树问题中的应用,包括判断相同树、对称二叉树、平衡二叉树、右视图、翻转二叉树、节点最大差值、不足节点和最长交错路径等经典LeetCode题目。通过实例代码展示了递归算法的实现和优化策略。
摘要由CSDN通过智能技术生成

一、学习视频

如何灵活运用递归?【基础算法精讲 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

2.101. 对称二叉树

递归

# 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)

3.110. 平衡二叉树

递归。不会,来自视频代码。

# 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

4.199. 二叉树的右视图

递归

# 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

三、课后作业

1.226. 翻转二叉树

递归

# 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

2.1026. 节点与其祖先之间的最大差值

不会,全都来自灵神题解(. - 力扣(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值,一个节点有左右两边两条路径到达。

3.1080. 根到叶路径上的不足节点

(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 来判断是不是叶子节点。

4.1372. 二叉树中的最长交错路径

(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

感谢你看到这里!一起加油吧!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值