代码随想录算法训练营第二十天|654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树

文章讲述了如何构建最大二叉树、合并两个二叉树以及在二叉搜索树中搜索特定值的方法,同时介绍了验证二叉搜索树的两种递归策略。
摘要由CSDN通过智能技术生成

654.最大二叉树 - 🔗

讲解 - 🔗
💡这道题跟代码随想录算法训练营第十八天的最后两道题非常相似,是同一种思路,只需要通过找出数组中最大值的下标来划分左右子树即可。

class Solution:
    def constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
        # 中左右->类似于前序遍历
        # 第一步:设定终止条件,如果nums为空,说明该子树为空
        if not nums:
            return None
        # 第二步:找出最大值并创建根节点
        max_val = max(nums)
        root = TreeNode(max_val)
        # 第三步:找出最大值下标(因为数组是不重复的)
        max_index = nums.index(max_val)
        # 第四步:划分左右子树
        left = nums[:max_index]
        right = nums[max_index + 1:]
        # 第五步:递归创建左右子树
        root.left = self.constructMaximumBinaryTree(left)
        root.right = self.constructMaximumBinaryTree(right)

        return root

617.合并二叉树 - 🔗

讲解 - 🔗
💡分为四种情况,其中root1和root2均为空为终止条件。

class Solution:
    def mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
        # 终止条件:当root1和root2均为空时
        if not root1 and not root2:
            return None

        # root1不为空,root2为空
        if root1 and not root2:
            root = TreeNode(root1.val)
            root.left = self.mergeTrees(root1.left, None)
            root.right = self.mergeTrees(root1.right, None)
        # root1为空,root2不为空
        elif not root1 and root2:
            root = TreeNode(root2.val)
            root.left = self.mergeTrees(None, root2.left)
            root.right = self.mergeTrees(None, root2.right)
        # root1和root2均不为空
        else:
            root = TreeNode(root1.val + root2.val)
            root.left = self.mergeTrees(root1.left, root2.left)
            root.right = self.mergeTrees(root1.right, root2.right)

        return root

700.二叉搜索树中的搜索 - 🔗

讲解 - 🔗

方法一:不了解二叉搜索树特性

💡这道题自己做的时候,根本不知道什么是二叉搜索树,就直接做了,所以不如增加判断节点值大小的方法高效。

class Solution:
    def match(self, root: Optional[TreeNode], val: int) -> None:
        if not root:
            return

        if root.val == val:
            self.res = root
            return

        left = self.match(root.left, val)
        right = self.match(root.right, val)

    def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
        self.res = None
        self.match(root, val)
        return self.res

方法二:递归
class Solution:
    def searchBST(self, root: TreeNode, val: int) -> TreeNode:
        # 为什么要有返回值: 
        #   因为搜索到目标节点就要立即return,
        #   这样才是找到节点就返回(搜索某一条边),如果不加return,就是遍历整棵树了。

        if not root or root.val == val: 
            return root

        if root.val > val: 
            return self.searchBST(root.left, val)

        if root.val < val: 
            return self.searchBST(root.right, val)
方法三:迭代
class Solution:
    def searchBST(self, root: TreeNode, val: int) -> TreeNode:
        while root:
            if val < root.val: root = root.left
            elif val > root.val: root = root.right
            else: return root
        return None

98.验证二叉搜索树 - 🔗

讲解 - 🔗
💡自己做的时候根本连暴力解法都没想到,直接想的是双指针,但是写着写着又绕进去了。

方法一:递归法 - 利用中序递增性质,转换成数组
class Solution:
    def __init__(self):
        self.vec = []

    def traversal(self, root):
        if root is None:
            return
        self.traversal(root.left)
        self.vec.append(root.val)  # 将二叉搜索树转换为有序数组
        self.traversal(root.right)

    def isValidBST(self, root):
        self.vec = []  # 清空数组
        self.traversal(root)
        for i in range(1, len(self.vec)):
            # 注意要小于等于,搜索树里不能有相同元素
            if self.vec[i] <= self.vec[i - 1]:
                return False
        return True
方法二:递归法 - 直接取该树的最小值
class Solution:
    def __init__(self):
        self.pre = None  # 用来记录前一个节点

    def isValidBST(self, root):
        if root is None:
            return True

        left = self.isValidBST(root.left)

        if self.pre is not None and self.pre.val >= root.val:
            return False
        self.pre = root  # 记录前一个节点

        right = self.isValidBST(root.right)
        return left and right
  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值