代码随想录算法训练营第十七天| 二叉树5—617. 合并二叉树,98. 验证二叉搜索树

今天的第二篇笔记,终于算是追上进度了,不过也跟今天题目较为简单有关,除了验证二叉树卡的久了点其余的感觉做起来都还顺手。654. 最大二叉树617. 合并二叉树700. 二叉搜索树中的搜索98. 验证二叉搜索树。像是最大二叉树就是用昨天的构造方法进行切分,二叉搜索树的搜索就是利用遍历以及二分。合并稍微做久了点是第一次接触两个数遍历,有点不清楚怎么写,但研究了下还是做完了。

617. 合并二叉树

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

其实遍历两个树加和的思路,就是利用一个树遍历,将另一棵树相同的节点的值加过来就行,就像代码中用的都是root1。相当于是把root1看成一个数组,把root2这个数组对应index的数加过来。当然也可以自己新创建一个树,然后把两棵树相加放进来。这题感觉迭代法比递归法难一些,主要是条件判断写多了一点,就是两棵树都有的节点,做加和,左无右有则直接左等于右,左有右无就是直接是root1,其余的都还是不算难。

# 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
        root1.val += root2.val
        root1.left = self.mergeTrees(root1.left,root2.left)
        root1.right = self.mergeTrees(root1.right,root2.right)
        return root1

    # 迭代
    def mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
        if not root1:
            return root2
        if not root2:
            return root1

        q = deque([(root1, root2)])
        while q:
            node1, node2 = q.popleft()
            node1.val += node2.val

            if node1.left and node2.left:
                q.append([node1.left,node2.left])
            elif not node1.left:
                node1.left = node2.left

            if node1.right and node2.right:
                q.append([node1.right,node2.right])
            elif not node1.right:
                node1.right = node2.right
        return root1

        

98. 验证二叉搜索树

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

有效 二叉搜索树定义如下:

  • 节点的左子树只包含 小于 当前节点的数。
  • 节点的右子树只包含 大于 当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

挺麻烦的一道题,一开始递归没有一点思路,就拿迭代先顺顺思路,然后做完发现怎么调试都不对,才发现是所有左子树和右子树自身必须也是二叉搜索树,这个条件没满足,就是单纯的比较左节点小于中间节点,右节点大于中间节点。之后学到了一种思路,有点像是所有队列那种的迭代方法,就是保存一组数据(root, min, max),每次弹出一个节点,然后赋值本节点,最小值,最大值。当往左节点开始走的时候,节点的最大值就发生变化,因为他的最大值的上限就是它的父节点。同理往右节点走的时候,节点的最小值也要变化。如果往左走过也往右走过,那么最大最小值都会有了限制。在每个节点处进行比较,不符合该节点的min< val < max就返回False,全遍历完了就是True。

然后是递归,懂了迭代思路之后再转化为递归就方便了(也可能是我练熟了hh),首先递归结束条件和迭代的结束条件都是一样的,不满足此节点的min < val < max。然后开始往两边分别进行递归,当两边都是True的时候,返回True,因为这个不像之前求路径的只需要走一边也行,是需要左右都符合条件,所以递归的时候用and。

# 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:
        # 队列迭代
        if not root:
            return None
        q = deque([(root,float("-inf"),float("inf"))])
        while q:
            node, min_val, max_val = q.popleft()
            if not (min_val < node.val < max_val):
                return False
            if node.left:
                q.append((node.left, min_val, node.val))
            if node.right:
                q.append((node.right, node.val, max_val))
        return True
    
    def isValidBST(self, root: Optional[TreeNode]) -> bool:
        #递归
        def validate(node, min_val, max_val):
            if not node:
                return True
            if not (min_val < node.val < max_val):
                return False
            node_left = validate(node.left,min_val,node.val)
            node_right = validate(node.right,node.val,max_val)
            return node_left and node_right

        return validate(root, float('-inf'), float('inf'))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值