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

654.最大二叉树 

题目链接 最大二叉树
解法
递归法:难度不大,采用的是前序遍历,因为先构造中间节点,然后递归构造左子树和右子树。
边界条件:无
时间复杂度:O(n)
空间复杂度:O(logn)
# 递归法
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def constructMaximumBinaryTree(self, nums):
        """
        :type nums: List[int]
        :rtype: TreeNode
        """
        if not nums:
            return None
        
        # 找到最大值,构造根节点
        max_val = max(nums)
        root = TreeNode(max_val)

        # 找到分割点,分割左右子树
        max_idx = nums.index(max_val)
        left_nums = nums[: max_idx]
        right_nums = nums[max_idx+1:]

        # 递归构造左右子树
        root.left = self.constructMaximumBinaryTree(left_nums)
        root.right = self.constructMaximumBinaryTree(right_nums)

        return root

617.合并二叉树 

题目链接合并二叉树

解法

递归法:使用前序遍历,采用新建root节点的方式比较直观。实现起来比较直观,难度不大。

迭代法:新建root发现非常写起来很麻烦,采用把右边的二叉树合并到左边的写法。注意每个子节点都是原地修改了自己的值,最终返回的是root1,而不是当前的子节点node1,这里我写错了,看了半天没发现怎么回事。

边界条件:

时间复杂度:

空间复杂度:

# 递归法
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def mergeTrees(self, root1, root2):
        """
        :type root1: TreeNode
        :type root2: TreeNode
        :rtype: TreeNode
        """
        if not root1 and not root2:
            return None
        if not root1:
            return root2
        if not root2:
            return root1
        
        root = TreeNode(root1.val + root2.val)
        root.left = self.mergeTrees(root1.left, root2.left)
        root.right = self.mergeTrees(root1.right, root2.right)

        return root
# 迭代法:广度优先遍历
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
import collections
class Solution(object):
    def mergeTrees(self, root1, root2):
        """
        :type root1: TreeNode
        :type root2: TreeNode
        :rtype: TreeNode
        """
        if not root1:
            return root2
        if not root2:
            return root1

        queue = collections.deque([(root1, root2)])
        while queue:
            for _ in range(len(queue)):
                node1, node2 = queue.popleft()
                node1.val += node2.val

                if node1.left and node2.left:
                    queue.append((node1.left, node2.left))
                elif not node1.left:
                    node1.left = node2.left

                if node1.right and node2.right:
                    queue.append((node1.right, node2.right))
                elif not node1.right:
                    node1.right = node2.right

        return root1             

700.二叉搜索树中的搜索 

题目链接二叉搜索树

解法

二叉搜索树是一个有序树:

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  • 它的左、右子树也分别为二叉搜索树。

递归法:主要是确定单层递归的逻辑。因为二叉搜索树的节点是有序的,所以可以有方向的去搜索。如果root->val > val,搜索左子树,如果root->val < val,就搜索右子树,最后如果都没有搜索到,就返回NULL。

迭代法:用常规的广度优先遍历可以轻松解决。但由于二叉搜索树的特性,也就是节点的有序性,可以不使用辅助栈或者队列就可以写出迭代法。中间节点如果大于val就向左走,如果小于val就向右走,简单到想哭。

边界条件:

时间复杂度:

空间复杂度

# 递归法
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def searchBST(self, root, val):
        """
        :type root: TreeNode
        :type val: int
        :rtype: TreeNode
        """
        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 TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def searchBST(self, root, val):
        """
        :type root: TreeNode
        :type val: int
        :rtype: TreeNode
        """
        while root:
            if root.val > val:
                root = root.left
            elif root.val < val:
                root = root.right
            else:
                return root
        return None

98.验证二叉搜索树

题目链接验证二叉搜索树

解法

二叉搜索树中,左子树的所有节点的值,都必须小于中间节点的值;右子树的所有节点的值,都必须大于中间节点的值。主要是所有节点,而不是左节点和右节点。所以可以用中序遍历得到所有节点的值,这个列表里的值必须是递增的序列。

这个题目的陷阱:不能单纯的比较左节点小于中间节点,右节点大于中间节点就完事了。比如下面的就不是二叉搜索树,因为右子树的6小于根节点10。

递归:实际就是二叉树的中序遍历,需要单独写个递归函数,独立出来。再判断遍历后的数组是否有序。

迭代法:实际就是用栈来实现二叉树的中序遍历。这个逻辑有点难理解,得时常复习。

边界条件:

时间复杂度:

空间复杂度

# 递归
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def isValidBST(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        # 中序遍历得到所有节点的值
        values = self.traversal(root)

        # 判断是否单挑递增
        for i in range(1, len(values)):
            if values[i] <= values[i-1]:
                return False
        return True
        
    def traversal(self, root):
        if not root:
            return []
        left = self.traversal(root.left)
        right = self.traversal(root.right)
        return left + [root.val] + right
# 迭代法
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def isValidBST(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        # 中序遍历得到所有节点的值
        values = self.iter(root)
        # 判断是否单调递增
        for i in range(1, len(values)):
            if values[i] <= values[i-1]:
                return False
        return True
        
    def iter(self, root):
        stack = []
        cur = root
        result = []
        while cur or stack:
            if cur:
                stack.append(cur)
                cur = cur.left
            else:
                cur = stack.pop()
                result.append(cur.val) 
                cur = cur.right
        return result
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值