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

654.最大二叉树 

文档讲解:代码随想录

题目链接:. - 力扣(LeetCode)

递归的三要素:

第一要素:明确这个函数想要干什么

传入一个数组,针对这个数组构造一个最大二叉树

第二要素:寻找递归结束条件

如果传入的是空那么就return 空

如果传入的只有一个节点,那么就返回这个节点

第三要素:找出函数的等价关系式

首先可以找出来最大的根节点root,就是数组中的最大值对应的节点

然后我们就需要分别构造根节点的左右子树。左子树是通过根节点左边的元素数组构造的最大二叉树,右子树是通过根节点的右边构造的最大二叉树,构造最大二叉树的过程即为递归

注意:要判断是否存在左右子树的情况(左右区间长度至少大于1,我们的递归判断条件是1才返回),再进行递归

递归中有时候写if,有时候不写if,主要是看终止条件,该终止条件限定了数组中至少有一个元素

class Solution:
    def constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
        ##递归终止条件
        if len(nums) == 1:
            return TreeNode(nums[0])
        
        ##找到数组中的最大值以及最大值对应的下标
        max_value,max_index = self.find_max_list(nums)

        #根节点是数组中的最大值
        root_val = max_value
        root = TreeNode(root_val)

        #根据根节点的位置划分左右子区间, 构造根节点的左右子树
        #注意index可能为0或者是数组的最后面,导致左右区间为空,如果左右区间为空,那么就没有左或者右子树
        if max_index >0:
            left = nums[:max_index]
            root.left = self.constructMaximumBinaryTree(left)
        if max_index < len(nums)-1:
            right = nums[max_index+1:]
            root.right = self.constructMaximumBinaryTree(right)
        return root
    def find_max_list(self,nums):
        #找到数组中的最大值以及最大值对应的下标
        max_value = 0
        max_index = 0
        for i in range(len(nums)):
            if nums[i] > max_value:
                max_value  = nums[i] 
                max_index = i 
        return max_value,max_index

617.合并二叉树 

文档讲解:代码随想录

题目链接:. - 力扣(LeetCode)

递归的三要素:

第一要素:明确这个函数想要干什么

传入两个二叉树,返回合并后的二叉树

第二要素:寻找递归结束条件

两棵树是一起遍历的

如果有一个树是空,那么就返回另一个树;如果两个树都是空,那么就return null(这种情况其实已经包含在了前面的条件中)

第三要素:找出函数的等价关系式

从根节点开始,直接去改tree1的结构,不再新定义一棵二叉树了,根节点合并完之后,就要去合并左右子树了,这时候就进入了递归

class Solution:
    def mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
        ###终止条件
        if root1 == None:
            return root2
        if root2 == None:
            return root1
        ##单层逻辑递推关系
        root1.val = root1.val + root2.val
        #递归
        root1.left = self.mergeTrees(root1.left,root2.left)
        root1.right = self.mergeTrees(root1.right,root2.right)

        return root1

700.二叉搜索树中的搜索 

文档讲解:代码随想录

题目链接:. - 力扣(LeetCode)

递归法

递归的三要素:

第一要素:明确这个函数想要干什么

给定二叉搜索树(BST)的根节点和一个值。在BST中找到节点值等于给定值的节点。 返回以该节点为根的子树。

第二要素:寻找递归结束条件

如果根节点的值即为要找的目标值,那么直接return 根节点即可

如果二叉树中只有一个节点,并且根节点的值与目标值不等,那么就返回Null

第三要素:找出函数的等价关系式

如果当前遍历的根节点的值大于目标值,那么接下来就遍历该节点的左子树

如果当前遍历的根节点的值小于目标值,那么接下来就遍历该节点的右子树

class Solution:
    def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
        ###递归终止条件
        if root == None:
            return None
        if root.val == val:
            return root
        if root.left==None and root.right == None and root.val != val:
            return None
        ###递归,根据二叉搜索树的特性,选择遍历左子树还是右子树
        if root.val > val:
            node = self.searchBST(root.left,val)
        else:
            node = self.searchBST(root.right,val)
        return node

迭代法

从根节点开始查询,根据二叉搜索树的特性,决定向右还是向左搜索

class Solution:
    def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
        while root:
            if root.val > val:
                root = root.left
            elif root.val < val:
                root = root.right
            else:
                return root
        if root == None:
            return None

 98.验证二叉搜索树 

文档讲解:代码随想录

题目链接:. - 力扣(LeetCode)

二叉搜索树的性质:

如果该二叉树的左子树不为空,则左子树上所有节点的值均小于它的根节点的值; 若它的右子树不空,则右子树上所有节点的值均大于它的根节点的值;它的左右子树也为二叉搜索树。

节点的位置越深,节点的值的限制就越多,所以我们可以判断节点是不是满足左右区间的限制,在遍历的过程中,不断去更新左右区间

递归的三要素:

第一要素:明确这个函数想要干什么

传入一个根节点,判断该节点对应的二叉树是否是二叉搜索树

并传入一个区间左端点,一个区间右端点,查看节点值是否满足区间限制,来辅助我们判断

第二要素:寻找递归结束条件

如果传入为空,返回True

如果节点的值不在区间中,那么return false

第三要素:找出函数的等价关系式

如果根节点满足要求,接下来要去看左右子树是否是二叉搜索树,在遍历过程中,如果向左遍历,那么就要更新区间的右端点,如果向右遍历,那么就要更新区间的左端点。

class Solution:
    def isValidBST(self, root: Optional[TreeNode]) -> bool:
        def helper(root,low,upper):
            ###递归终止条件
            if not root:
                return True
            if root.val<=low or root.val>=upper: #不要忘记等于的情况
                return False
            ###递归遍历左右子树
            left = True
            right = True
            if root.left:
                left = helper(root.left,low,root.val)
            if root.right:
                right =  helper(root.right,root.val,upper)
            return left and right
        return  helper(root,float('-inf'),float('inf')) #刚开始根节点的范围是任意的

没有写出来的想法,先不看了

(如果传入节点不是空节点

我们需要递归验证该节点的左子树和右子树是否是二叉搜索树

并且,如果是,那么此时我们还不能确定传入节点是否就是二叉搜索树,因为可能出现这种情况

所以我们还需要比较左子树的最大值是否比节点小,右子树的最小值是否比节点大,但是如何去找左子树的最大值和右子树的最小值呢)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值