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

109 阅读3分钟

654.最大二叉树

1. 第一想法

当前数组nums中最大值的位置即为中序遍历的根节点位置。 整体相当于将数组看作中序遍历的序列数组, 只不过在找中序遍历序列的根节点时:

  • 不是通过后序遍历或前序遍历的首尾元素节点位置来判断;
  • 而是通过对整个数组求最大值来判断。 其余的做法基本一致。 如何找到一个数组的最大值,我通常的做法是:
  • 设置一个键值对<key, value>
  • 当找到比key更大的元素时,更新这个键值对,其中键为最大元素,值为该元素的位置。 遍历整个数组,就可以找到该数组的最大值的位置。

# 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 len(nums) == 0:
            return None
        max_loc = [-1, -1]
        for idx in range(len(nums)):
            if nums[idx] > max_loc[0]:
                max_loc[0] = nums[idx]
                max_loc[1] = idx
        max_idx = max_loc[1]
        left_child = self.constructMaximumBinaryTree(
            nums=nums[:max_idx]
        )
        right_child = self.constructMaximumBinaryTree(
            nums=nums[max_idx + 1:]
        )
        root = TreeNode(
            val=max_loc[0],
            left=left_child,
            right=right_child
        )
        return root

2. 学习时长

15分钟。

617.合并二叉树

1. 第一想法

同样要遍历一颗二叉树,只不过遇到的终止条件,不是Root为空,而是两个Root都为空。 如果只有一个Root为空,另一个Root不为空,那么这里应该有一个节点。 如果两个Root同时不为空,那么我们应该将他们两个加起来。


# 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) and (not root2):
            return None
        if root1 and (not root2):
            return root1
        if (not root1) and root2:
            return root2
        left_child = self.mergeTrees(
            root1=root1.left,
            root2=root2.left
        )
        right_child = self.mergeTrees(
            root1=root1.right,
            root2=root2.right
        )
        root = TreeNode(
            val=root1.val + root2.val,
            left=left_child,
            right=right_child
        )
        return root

2. 读文档

文档链接 递归法肯定没有问题,迭代法我还没做,有机会再做迭代法。

3. 学习时长

23分钟。

700.二叉搜索树中的搜索

1. 第一想法

这道题也非常的简单,根据二叉树搜索数的基本特性就可以解。 如果当前节点的值小于我们要找的值,那我们就应该向右子树递归。 反之,我们应该向左子树递归。 如果当前根节点为空,那么说明没有找到。 如果当前根节点和值匹配,那么说明找到了。


# 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
        else:
            if root.val == val:
                return root
            if root.val < val:
                return self.searchBST(
                    root=root.right,
                    val=val
                )
            if root.val > val:
                return self.searchBST(
                    root=root.left,
                    val=val
                )
                

2. 实现上的困难

如果我们不写左右子树调用函数后的两个return,返回的就是None, 因为虽然上一层返回了,但是也只是返回到这一层的函数中,并没作为最后的结果返回,所以要逐层返回。

3. 学习时长

40分钟(找了半天bug)

98.验证二叉搜索树

1. 第一想法

直接搞个中序遍历,把遍历的结果用一个list存起来。 最后遍历整个list,检验单调性即可。


# 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.list = []
    def dfs(self, root):
        if not root:
            return
        else:
            node_stack = [root]
            while node_stack:
                node = node_stack.pop()
                if (not node.left) and (not node.right):
                    self.list.append(node.val)
                    continue
                if node.right:
                    node_stack.append(node.right)
                node_stack.append(
                    TreeNode(
                        val=node.val
                    )
                )
                if node.left:
                    node_stack.append(node.left)
                
    def isValidBST(self, root: Optional[TreeNode]) -> bool:
        self.dfs(root)
        for idx in range(len(self.list) - 1):
            if self.list[idx] >= self.list[idx + 1]:
                return False
        return True

2. 实现过程中遇到的困难

  1. 因为中序遍历后后序遍历,stack都会再无条件加一遍砍掉左右子树的root到right和left之间,所以如果是叶子节点,加完list后就应该skip这次循环,如果不skip,会再把这个叶子节点加进去,这样就死循环了。
  2. 二叉搜索树是严格单调递增的,不存在相等元素的情况。

3. 看文档

文档链接 和我想的一样。

学习时长

30分钟。