Day17 第六章 二叉树Part5

任务

654. 最大二叉树

给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建:
创建一个根节点,其值为 nums 中的最大值。
递归地在最大值 左边 的 子数组前缀上 构建左子树。
递归地在最大值 右边 的 子数组后缀上 构建右子树。

思路

做了昨天的利用前中序(或者中后)数组构建二叉树,就会做这道题,思路基本一致。按照算法,分割数组区域并创建即可。

class Solution:
    def constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
        if len(nums)==0: return None
        index = 0 
        maxValue = float('-inf')
        
        for i in range(len(nums)):
            if nums[i] > maxValue:
                maxValue = nums[i]
                index = i
        
        root = TreeNode(nums[index])
        leftNums = nums[:index]
        rightNums = nums[index+1:]
        root.left = self.constructMaximumBinaryTree(leftNums)
        root.right = self.constructMaximumBinaryTree(rightNums)
        return root

617. 合并二叉树

想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。
返回合并后的二叉树。

思路

单层递归逻辑: 分情况合并当前节点

  1. 两树都不存在节点
  2. 两树只有一个存在,则返回有的那个
  3. 都存在,则将节点和相加并构建成新节点,并且分别递归的合并其左右子树

这道题也是结合了遍历过程和传统递归的思路

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
        if root1 and root2: 
            newRoot = TreeNode(root1.val + root2.val)
            newRoot.left = self.mergeTrees(root1.left,root2.left)
            newRoot.right = self.mergeTrees(root1.right,root2.right)
            return newRoot

700.二叉搜索树中的搜索

思路

这道题很简单,递归的思路就是遍历节点,找到就返回,否则根据条件向相应的子树去找。
迭代的思路是,val较小就往当前节点左子树找,val较大就往当前节点的右子树找,直到找到或者到达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 val < root.val: return self.searchBST(root.left,val)
        else: return self.searchBST(root.right,val)

# 迭代法
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   

98. 验证二叉搜索树

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

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

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

思路(错误)

想当然的解法是直接用递归,判断当前节点的局部逻辑是否满足(它比它右节点小,比它左节点大),然后再判断左右子树是否满足,全部满足则返回True。可惜这种思路是错误的。。反例 [5,4,6,null,null,3,7], 某节点必须比他的左子树所有的值小,右子树所有的值大。这个7大于了根节点的大小,违反了BST的定义

class Solution:
    def isValidBST(self, root: Optional[TreeNode]) -> bool:
        if not root: return True
        elif not root.left and not root.right: return True
        elif root.left and not root.right:
            if root.val > root.left.val: return True
            else:return False
        elif not root.left and root.right:
            if root.val < root.right.val: return True
            else:return False    
        else: 
            if root.val > root.left.val and  root.val < root.right.val:
                return self.isValidBST(root.left ) and self.isValidBST(root.right)
            else:
                return False

思路(正确)

判断中序序列是否有序

class Solution:
    def isValidBST(self, root: Optional[TreeNode]) -> bool:
        lst = []
        self.inorder(root,lst)
        print(lst)
        for i in range(len(lst)-1):
            if lst[i] >= lst[i+1]: return False
        return True

    def inorder(self,root,lst):
        if not root: return None
        
        self.inorder(root.left,lst)
        lst.append(root.val)
        self.inorder(root.right,lst)

心得体会

更娴熟的掌握了单纯递归逻辑(局部+递归),以及递归序遍历流程的思路。

posted @   haohaoscnblogs  阅读(12)  评论(0)    收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示