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

写在前边的话

        二叉树训练的第五天啦,理论基础见下边第一天链接,今天也要加油呀!

       理论基础知识

654.最大二叉树 

题目链接

        力扣题目链接

题目难度

        中等

看到题目的第一想法

        有了昨天的训练,看到题目就想到了昨天二叉树构造的递归算法,不同的是这道题目给的是一组数组,而中节点的确定是数组中的最大值,但是实现的算法逻辑是一样的。
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 not nums:
            return None

        root_val = max(nums)
        root = TreeNode(root_val)

        root_index = nums.index(root_val)

        left_nums = nums[:root_index]
        right_nums = nums[root_index+1:]

        root.left = self.constructMaximumBinaryTree(left_nums)
        root.right = self.constructMaximumBinaryTree(right_nums)

        return root

看完代码随想录之后的总结

文章讲解

        代码随想录654.最大二叉树文章讲解

视频讲解

        代码随想录654.最大二叉树视频讲解

解题思路

        1. 递归法:前序遍历

        2. 递归三步曲:

            入参:要分隔的数组,返回值:根节点。

            终止条件:分隔出来的数组为空了说明已经到叶子节点了,return None。

            单次递归逻辑:1)确认数组中最大值作为当前中节点  2)确认数组中最大值下标作为分隔点 3)以最大值分隔数组为左右两部分  4)递归:分隔出的左右数组分别作为左右子树进行递归操作。

代码编写
python

        同第一想法

java

617.合并二叉树

题目链接

        力扣题目链接

题目难度

        简单

看到题目的第一想法

        看到题目的第一想法是想到用递归了,整体思路是有的,但是终止条件没有处理好,想到的是节点为空了就返回空,处理的不好,导致后边的单次递归逻辑处理比较麻烦,要去考虑左右子节点情况,最终也没处理好。

看完代码随想录之后的总结

文章讲解

        代码随想录617. 合并二叉树文章讲解

视频讲解

        代码随想录617. 合并二叉树视频讲解

解题思路

        1. 递归法:递归顺序前中后都可以

        2. 递归三步曲:1)入参:要合并的二叉树;返回值:合并二叉树的根节点。2)终止条件:一个二叉树为空则返回另一个。3)单次递归逻辑:合并当前两个节点作为新的节点,递归遍历左右子树。

代码编写
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 not root1:
            return root2

        if not root2:
            return root1

        root_val = root1.val + root2.val
        root = TreeNode(root_val)

        root.left = self.mergeTrees(root1.left, root2.left)
        root.right = self.mergeTrees(root1.right, root2.right)

        return root
java

700.二叉搜索树中的搜索

题目链接

        力扣题目链接

题目难度

        简单

看到题目的第一想法

        看到题目的第一想法是使用层序遍历,使用队列实现。

        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 not root:
            return None

        
        queue = collections.deque([root])
        while queue:
            n = len(queue)
            for i in range(n):
                node = queue.popleft()
                if node.val == val:
                    return node
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        return None

不足:其实这样的写法是没有利用到二叉搜索树的有序性,我写的时候也意识到了这一点,可是没想好怎么去利用这个特性。

二叉搜索树性质:若左子树非空,则左子树的所有节点值均小于根节点值;若右子树非空,右子树中所有节点的值均大于根节点的值;左右子树也均具有这种性质。 

注意:是所有节点。

看完代码随想录之后的总结

文章讲解

        代码随想录700.二叉搜索树中的搜索文章讲解

视频讲解

          代码随想录700.二叉搜索树中的搜索视频讲解

解题思路

        1. 递归法:遍历顺序按照二叉树的有序性来进行有方向的遍历。

           递归三部曲:1)入参:根节点和目标值;返回值:目标子树。2)终止条件:若节点为空或者找到了目标节点则返回当前节点。3)单次递归逻辑:如果目标值小于当前节点的值,则向左子树遍历,如果目标值大于当前节点的值,则向右子树遍历。

        2. 迭代法:在迭代过程中也要应用到二叉搜索树的顺序性进行有方向的遍历

代码编写
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 not root or root.val == val:
            return root

        res = None
        if val < root.val:
            res = self.searchBST(root.left, val)

        if val > root.val:
            res = self.searchBST(root.right, val)

        return res
        

#*******************************************************************************

# 迭代法
# 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]:
        while root:
            if val < root.val:
                root = root.left
            elif val > root.val:
                root = root.right
            else:
                return root
        return None
java

98.验证二叉搜索树

题目链接

        力扣题目链接

题目难度

        中等

看到题目的第一想法

        看到第一题目的第一想法就是使用递归法进行遍历,但是却进入一个误区,想着是指判断当前节点的左节点小于当前节点,当前节点的右节点大于右节点,而忽略了二叉搜索树真正的顺序性(见上一题)。

看完代码随想录之后的总结

文章讲解

        代码随想录98.验证二叉搜索树文章讲解文章讲解

视频讲解

       代码随想录98.验证二叉搜索树视频讲解

解题思路

        1. 递归中序遍历,利用中序递增的性质,节点值保存在数组中,检查数组是不是递增的。

        2. 递归中序遍历,前一个节点的值大于当前节点值,初始化pre节点为None。

代码编写
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:
        
        res = []
        def dsf(root):
            if not root:
                return
            dsf(root.left)
            res.append(root.val)
            dsf(root.right)

        dsf(root)
        for i in range(1, len(res)):
            if res[i] <= res[i-1]:
                return False
        return True

# ***********************************************************

# 递归+双指针(初始化pre为None)
# 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 __init__(self):
        self.pre = None
    def isValidBST(self, root: Optional[TreeNode]) -> bool:
        if not root:
            return True

        left_res = self.isValidBST(root.left)  # 左

        # 中
        if self.pre and self.pre.val >= root.val: 
            return False
        self.pre = root

        right_res = self.isValidBST(root.right)  # 右

        return left_res and right_res
java

今日总结

        今天大部分的题目都是和二叉搜索树相关的题目,要明确:1)二叉搜索树的性质,是左子树的节点值均小于根节点的值,右子树所有节点的值均大于根节点的值,左右子树也同样满足这个性质。2)根据二叉搜索树的性质利用中序遍历的话,保存在数组中,数组是升序的。因此在解决二叉树验证题目的时候一是可以利用数组的这个性质,二是可以使用双指针在中序遍历的过程中来进行递归判断。总的来说就是二叉搜索题目要用到其顺序性,另外二叉搜索树一般用到是中序遍历。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值