秋招算法备战第20天 | 654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树

654. 最大二叉树 - 力扣(LeetCode)

一开始的代码版本如下所示

python 复制代码
# 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 constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
        if len(nums) == 0:
            return None
        max_num = max(nums)
        max_index = nums.index(max_num)
        root = TreeNode(val=max_num)
        root.left = self.constructMaximumBinaryTree(nums[:max_num])
        root.right = self.constructMaximumBinaryTree(nums[max_num:])
        return root

这里犯了个低级错误,递归调用的时候参数应该分别是nums[:max_index]以及nums[max_index+1:],需要把当前这个元素给略掉,修正后AC的代码如下

python 复制代码
# 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 constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
        if len(nums) == 0:
            return None
        max_num = max(nums)
        max_index = nums.index(max_num)
        root = TreeNode(val=max_num)
        root.left = self.constructMaximumBinaryTree(nums[:max_index])
        root.right = self.constructMaximumBinaryTree(nums[max_index+1:])
        return root

617. 合并二叉树 - 力扣(LeetCode)

递归方法构造,使用递归三部曲依次分析

python 复制代码
# 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 mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
        if root1 == None and root2 == None:
            return None
        
        val1 = 0 if root1 == None else root1.val
        val2 = 0 if root2 == None else root2.val
        cur = TreeNode(val1+val2)

        root1_left, root1_right = (None, None) if root1 == None else (root1.left, root1.right)
        root2_left, root2_right = (None, None) if root2 == None else (root2.left, root2.right)

        cur.left = self.mergeTrees(root1_left, root2_left)
        cur.right = self.mergeTrees(root1_right, root2_right)
        
        return cur

看了下参考代码,发现有两点可以优化:

  1. 如果有一个为空可以直接剪枝
  2. 可以不用新建结点而是直接修改root1结点
python 复制代码
# 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 mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
        # 递归终止条件: 
        #  但凡有一个节点为空, 就立刻返回另外一个. 如果另外一个也为None就直接返回None. 
        if not root1: 
            return root2
        if not root2: 
            return root1
        # 上面的递归终止条件保证了代码执行到这里root1, root2都非空. 
        root1.val += root2.val # 中
        root1.left = self.mergeTrees(root1.left, root2.left) #左
        root1.right = self.mergeTrees(root1.right, root2.right) # 右
        
        return root1 # ⚠️ 注意: 本题我们重复使用了题目给出的节点而不是创建新节点. 节省时间, 空间. 

700. 二叉搜索树中的搜索 - 力扣(LeetCode)

根据二叉搜索树性质可得

python 复制代码
# 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 searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
        if root == None:
            return None
        if root.val == val:
            return root
        elif root.val > val:
            return self.searchBST(root.left, val)
        else:
            return self.searchBST(root.right, val)

98. 验证二叉搜索树 - 力扣(LeetCode)

利用二叉树特性,进行中序遍历,在遍历过程中判断结点的值是否是递增的,并且加入了一些剪枝降低某些情况的时间复杂度

python 复制代码
# 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 isValidBST(self, root: Optional[TreeNode]) -> bool:
        last_num = float('-inf')

        def traversal(cur):
            nonlocal last_num
            if cur == None:
                return True

            left_res = traversal(cur.left)
            if not left_res:
                return False
            
            if last_num >= cur.val:
                return False
            last_num = cur.val

            right_res = traversal(cur.right)
            if not right_res:
                return False
            return True

        return traversal(root) 

GPT4对于上面代码给出了一点建议,即在判断None的时候使用is而不是==

is None== None在大多数情况下都能得到相同的结果,但是它们的检查机制是不同的。

  • is None 是检查对象的身份,也就是说它检查两个引用是否指向内存中的同一个对象。在Python中,None是一个单例对象,也就是说在内存中只有一个None。因此,is None就是检查一个对象是否就是这个特定的None对象。

  • == None 是检查对象的值,也就是说它检查两个对象的值是否相等。对于None来说,这通常和is None得到相同的结果。但是,如果一个对象重写了__eq__()方法来改变==的行为,那么== None可能会得到不同的结果。

因此,如果你想要检查一个对象是否为None,那么应该使用is None,因为这样可以保证无论__eq__()如何被重写,你都可以得到正确的结果。

这就是is None== None的主要区别。在Python社区,通常推荐使用is Noneis not None来检查一个对象是否为None

总结

  1. 递归中记得考虑剪枝来降低某些情况下的时间复杂度
  2. 在python中,判断是否为None推荐用is和is not
相关推荐
先做个垃圾出来………1 小时前
差分数组(Difference Array)
java·数据结构·算法
hansang_IR1 小时前
【题解】洛谷 P4286 [SHOI2008] 安全的航线 [递归分治]
c++·数学·算法·dfs·题解·向量·点积
乐迪信息1 小时前
乐迪信息:AI摄像机在智慧煤矿人员安全与行为识别中的技术应用
大数据·人工智能·算法·安全·视觉检测
多恩Stone2 小时前
【3DV 进阶-2】Hunyuan3D2.1 训练代码详细理解下-数据读取流程
人工智能·python·算法·3d·aigc
惯导马工3 小时前
【论文导读】IDOL: Inertial Deep Orientation-Estimation and Localization
深度学习·算法
老姜洛克3 小时前
自然语言处理(NLP)之n-gram从原理到实战
算法·nlp
CoovallyAIHub3 小时前
基于YOLO集成模型的无人机多光谱风电部件缺陷检测
深度学习·算法·计算机视觉
CoovallyAIHub3 小时前
几十个像素的小目标,为何难倒无人机?LCW-YOLO让无人机小目标检测不再卡顿
深度学习·算法·计算机视觉
怀旧,4 小时前
【C++】19. 封装红⿊树实现set和map
linux·c++·算法
往事随风去4 小时前
Redis的内存淘汰策略(Eviction Policies)有哪些?
redis·后端·算法