秋招算法备战第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
相关推荐
hsling松子4 小时前
使用PaddleHub智能生成,献上浓情国庆福
人工智能·算法·机器学习·语言模型·paddlepaddle
dengqingrui1234 小时前
【树形DP】AT_dp_p Independent Set 题解
c++·学习·算法·深度优先·图论·dp
C++忠实粉丝4 小时前
前缀和(8)_矩阵区域和
数据结构·c++·线性代数·算法·矩阵
ZZZ_O^O5 小时前
二分查找算法——寻找旋转排序数组中的最小值&点名
数据结构·c++·学习·算法·二叉树
CV-King5 小时前
opencv实战项目(三十):使用傅里叶变换进行图像边缘检测
人工智能·opencv·算法·计算机视觉
代码雕刻家6 小时前
数据结构-3.9.栈在递归中的应用
c语言·数据结构·算法
雨中rain6 小时前
算法 | 位运算(哈希思想)
算法
Kalika0-07 小时前
猴子吃桃-C语言
c语言·开发语言·数据结构·算法
sp_fyf_20248 小时前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-02
人工智能·神经网络·算法·计算机视觉·语言模型·自然语言处理·数据挖掘
我是哈哈hh9 小时前
专题十_穷举vs暴搜vs深搜vs回溯vs剪枝_二叉树的深度优先搜索_算法专题详细总结
服务器·数据结构·c++·算法·机器学习·深度优先·剪枝