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

61 阅读2分钟

654. 最大二叉树

代码随想录视频讲解

代码随想录文章讲解

递归法分割nums

class Solution:
    def constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
        if len(nums) == 0:
            return None
​
        max_val = max(nums)
        max_index = nums.index(max_val)
        left_tree = nums[:max_index]
        right_tree = nums[max_index+1:]
​
        node = TreeNode(max_val)
        node.left = self.constructMaximumBinaryTree(left_tree)
        node.right = self.constructMaximumBinaryTree(right_tree)
​
        return node

优化递归法,使用下标分割nums

class Solution:
    """最大二叉树 递归法"""
​
    def constructMaximumBinaryTree(self, nums: List[int]) -> TreeNode:
        return self.traversal(nums, 0, len(nums))
    
    def traversal(self, nums: List[int], begin: int, end: int) -> TreeNode:
        # 列表长度为0时返回空节点
        if begin == end:
            return None
        
        # 找到最大的值和其对应的下标
        max_index = begin
        for i in range(begin, end):
            if nums[i] > nums[max_index]:
                max_index = i
        
        # 构建当前节点
        root = TreeNode(nums[max_index])
        
        # 递归构建左右子树
        root.left = self.traversal(nums, begin, max_index)
        root.right = self.traversal(nums, max_index + 1, end)
        
        return root

617. 合并二叉树

代码随想录视频讲解

代码随想录文章讲解

递归法

class Solution:
    def mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
        if not root1 and not root2:
            return None
​
        if not root1 and root2:
            return root2
​
        if root1 and not root2:
            return root1
​
        # root
        node = TreeNode(root1.val+root2.val)
        # left
        node.left = self.mergeTrees(root1.left, root2.left)
        # right
        node.right = self.mergeTrees(root1.right, root2.right)
​
        return node

递归法优化(不创建新node)

class Solution:
    def mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
        if not root1:
            return root2
        
        if not root2:
            return root1
        
        # root
        root1.val += root2.val
        # left
        root1.left = self.mergeTrees(root1.left, root2.left)
        # right
        root1.right = self.mergeTrees(root1.right, root2.right)
        
        return root1

迭代法

class Solution:
    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:
            cur1 = q.popleft()
            cur2 = q.popleft()
​
            # q only deal with the nodes that tree1 and tree2 both have at the same position
            if cur1.left and cur2.left:
                q.append(cur1.left)
                q.append(cur2.left)
            if cur1.right and cur2.right:
                q.append(cur1.right)
                q.append(cur2.right)
​
            cur1.val += cur2.val
            if not cur1.left and cur2.left:
                cur1.left = cur2.left
            if not cur1.right and cur2.right:
                cur1.right = cur2.right
​
        return root1

700. 二叉搜索树中的搜索

代码随想录视频讲解

代码随想录文章讲解

迭代法

  • 利用BST的左小右大的属性进行搜索
class Solution:
    def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
        cur = root
        while cur:
            if cur.val == val:
                return cur
            if cur.val > val:
                cur = cur.left
            else:
                cur = cur.right
​
        return None

递归法

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

98. 验证二叉搜索树

代码随想录视频讲解

代码随想录文章讲解

递归法

  • BST的中序遍历是有序的(升序)
  • 遇到BST,一定要想着中序遍历,才能用上它的特性
class Solution:
    def isValidBST(self, root: Optional[TreeNode]) -> bool:
        pre = None
​
        def _helper(root):
            if not root:
                return True
​
            # left
            left = _helper(root.left)
​
            # root
            nonlocal pre
            if pre and pre.val >= root.val:
                return False
            pre = root
​
            # right
            right = _helper(root.right)
​
            return left and right
​
        return _helper(root)

迭代法

  • 统一迭代法的中序遍历
class Solution:
    def isValidBST(self, root: Optional[TreeNode]) -> bool:
        if not root:
            return True
​
        pre = None
        stack = deque([root])
​
        while stack:
            cur = stack.pop()
            if cur:
                # right
                if cur.right:
                    stack.append(cur.right)
​
                # root
                stack.append(cur)
                stack.append(None)
​
                # left
                if cur.left:
                    stack.append(cur.left)
            else:
                cur = stack.pop()
                if pre and pre.val >= cur.val:
                    return False
                pre = cur
​
        return True