代码随想录算法训练营Day20|Leetcode617/654/700/98

Leetcode617

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

给你两棵二叉树: root1 和 root2 。

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

返回合并后的二叉树。

注意: 合并过程必须从两个树的根节点开始。

思路:第一反应是递归!那么既然是递归,用那种顺序去遍历呢?这道题用三种遍历方式的任意一种都可以!

递归三部曲写起来:

                1:需要传入的参数,两个二叉树的根节点,返回值是合并之后的新根节点

                2:递归的终止条件:因为是传入了两个树,那么就有两个树遍历的节点t1 和 t2,如果t1 == NULL 了,两个树合并就应该是 t2 了啊(如果t2也为NULL也无所谓,合并之后就是NULL)。

反过来如果t2 == NULL,那么两个数合并就是t1(如果t1也为NULL也无所谓,合并之后就是NULL)。                

                3:单层循环逻辑:我们对t1这棵树进行结构的修改,而不迎娶另外构造一棵二叉树

所以t1的左子树合并t2的左子树,t1的右子树合并t2的右子树.

                最后t1的根节点就是合并的新根节点,这里这一行逻辑可以写在任意位置。写在前面就是前序遍历,写中间就是中序遍历,写最后就是后序遍历

代码:

def mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
        if root1==None:
            return root2
        if root2==None:
            return root1 
        #中
        root1.val+=root2.val 
        #对t1的左子树进行递归 然后分别传入两棵树的左子树
        root1.left = self.mergeTrees(root1.left,root2.left)
        #对t1的右子树进行改造 然后分别传入两棵树的右子树
        root1.right =self.mergeTrees(root1.right,root2.right)
        return root1 
        """整体是前序遍历的思想 直接对tree1进行改造 而不去定义一个新的二叉树"""

Leetcode654构造最大二叉树

https://leetcode.cn/problems/maximum-binary-tree/

 

 

思路:首先这道题要明确,如果当前数组中只剩一个节点的时候,那么它既是root也是叶子节点。

所以我们的终止条件就是当前数组的长度至少为1

递归三部曲:

1.递归传入的参数,分别传入左子树和右子树

2.终止条件已经写过了,在上面。

3.单层循环条件,这里我们已经确定数组中root节点的下标,所以根绝下标的左右两边确定左右子树的位置。

根据中序遍历(左中右),这里我们遵守左闭右开原则,从0:index为左区间,index+1:len(nums)-1为有区间。

然后判断index>0和小于len(nums)-1,因为我们的终止条件是要保证至少有一个元素。

所以要加上if判断

为什么有时候的递归就不用写if呢?

因为if判断写不写取决于我们的终止条件

代码:

def constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
        if len(nums)==1:
            return TreeNode(nums[0]) 
        index = 0 
        max_value = 0 
        for i in range(len(nums)):
            if nums[i]>max_value:
                max_value = nums[i]
                index = i 
        root = TreeNode(max_value)
    #遵循左闭右开原则
        #开始递归
        #根据终止条件 至少有一个元素
        if index>0:
            left = nums[0:index]
            root.left = self.constructMaximumBinaryTree(left)
        if index<len(nums)-1:
            right = nums[index+1:]
            root.right  = self.constructMaximumBinaryTree(right)
        return root 

Leetcode700二叉搜索树中的搜索

力扣

给定二叉搜索树(BST)的根节点 root 和一个整数值 val。

你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null 。

思路:老规矩递归!

思路很简单,就是递归遍历节点查找有没有符合的值然后然返回以当前值为根节点的子树

递归三部曲:

递归终止条件:到空节点都没有符合的就直接返回none

递归传入参数:当前根节点的左子树,右子树,val

单层循环逻辑:如果有符合的就直接返回root就好了

left = self.searchBST(root.left,val)

right = self.searchBST(root.right,val)

#判断节点存不存在

        if left:

#返回以当前节点为根节点的子树

            return left

        if right:

            return right

        return None

代码:

def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
        #终止条件
        if root==None:
            return None
        if root.val==val:
            return root
        left = self.searchBST(root.left,val)
        right = self.searchBST(root.right,val)
        if left:
            return left
        if right:
            return right
        return None

Leetcode98 验证二叉搜索树

https://leetcode.cn/problems/validate-binary-search-tree/

 

思路:

                二叉搜索树定义:

                左子树所有节点<根节点

                右子树所有节点>根节点

其次:根据二叉搜索树的特性,可以看出他是 左<中<右,也就是一个递增数组对不对?

是不是刚好是我们的中序遍历的顺序左中右?

也就是说 我们需要一个数组记录每个节点 然后判断这个数组是不是一个递增数组就可以了!

这里有几个误区,我一开始也陷进去了:

(来自代码随想录)

递归三部曲:终止条件:如果是空节点,是不是二叉搜索树呢?他也是 二叉搜索树可以为空,所以返回true.

                        传入参数:一个根节点,一个空数组(用于添加每个节点的值)

                        单层循环逻辑:按照左中右的顺序来就可以。

代码:

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


    def inorder(self,root,res):
        if root==None:
            return True
        #中序遍历 左中右
        self.inorder(root.left,res)
        res.append(root.val)
        self.inorder(root.right,res)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值