代码随想录算法训练营第十七天|leetcode654. 最大二叉树、leetcode617.合并二叉树、leetcode700.二叉搜索树中的搜索、leetcode98.验证二叉搜索树

1 leetcode654. 最大二叉树

题目链接:654. 最大二叉树 - 力扣(LeetCode)

文章链接:代码随想录

视频链接:又是构造二叉树,又有很多坑!| LeetCode:654.最大二叉树_哔哩哔哩_bilibili

思路:跟上一道题从中序后序中返回一个二叉树,好了,同理的思路就做出来咯,哈哈哈哈哈哈

1.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 constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
        if len(nums) == 0:
            return None
        root_val = max(nums)
        root = TreeNode(root_val)
        if len(nums) == 1:
            return root
        ind = 0
        for i in range(len(nums)):
            if nums[i] == root_val:
                ind = i
                break
        nums_left = nums[:ind]
        nums_right = nums[ind+1:]
        root.left = self.constructMaximumBinaryTree(nums_left)
        root.right = self.constructMaximumBinaryTree(nums_right)
        return root

1.2视频后的思路

差异就是这个构造的二叉树,因为一定有值,所以没必要对其为0进行判断,如果有一个值的话,就可以进行返回

# 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) == 1:
            return TreeNode(nums[0])
        root = TreeNode(0)
        maxval = 0
        maxind = 0
        for i in range(len(nums)):
            if nums[i]>maxval:
                maxval = nums[i]
                maxind = i
        root.val = maxval
        if maxind>0:
            root.left = self.constructMaximumBinaryTree(nums[:maxind])
        if maxind<len(nums)-1:
            root.right = self.constructMaximumBinaryTree(nums[maxind+1:])
        return root

1.3 本题小结

  1. 这道题的第一种思路就是使用前序中序构造一个唯一的二叉树,这么做可以写出来代码,但是会非常的冗余
  2. 然后就是第二种递归,首先判断什么时候终止,就是这个二叉树只有一个数值的时候,可以直接进行返回,这里发现由于递归的原因,如果直接将数据使用max函数的话会直接报错

2 leetcode617.合并二叉树

题目链接:617. 合并二叉树 - 力扣(LeetCode)

文章链接:代码随想录

视频链接:一起操作两个二叉树?有点懵!| LeetCode:617.合并二叉树_哔哩哔哩_bilibili

思路:开始的时候,我想的是这个直接进行合并就行,但是发现有的二叉树我连分开都不能分开,还是直接看视频来写吧

2.1 视频后的思路

思路

不进行新的二叉树定义,覆盖的方法,就是将另一个二叉树的值加过去就好了,其实理论上真的没新的,就是自己想不出来

2.1.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 mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
        if root1==None:
            return root2
        if root2 == None:
            return root1
        
        root1.val += root2.val
        root1.left = self.mergeTrees(root1.left,root2.left)
        root1.right = self.mergeTrees(root1.right,root2.right)
        return root1
2.1.2 定义一个新的二叉树
# 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 root1==None:
            return root2
        if root2 == None:
            return root1
        root = TreeNode(0)
        root.val = root1.val +root2.val
        root.left = self.mergeTrees(root1.left,root2.left)
        root.right = self.mergeTrees(root1.right,root2.right)
        return root

2.2 本题小结

  1. 写到这里的时候,我突然发现,这种题真的写的不难,主要是思路上会有想不到的地方,每次卡壳了,但是听视频听了一点就会了
  2. 二叉树合并其实和两数相加也是同样的原理,要学会举一反三呀

3 leetcode700.二叉搜索树中的搜索

题目链接:700. 二叉搜索树中的搜索 - 力扣(LeetCode)

文章链接:代码随想录

视频链接:不愧是搜索树,这次搜索有方向了!| LeetCode:700.二叉搜索树中的搜索_哔哩哔哩_bilibili

思路:看到题目想使用前序遍历,如果找到了这个值,那就可以返回这个树了;但是吧写的时候,不会了,,

3.1 基础知识

二叉搜索树

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

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

3.2 视频后的思路

3.2.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 root ==None or root.val == val:
            return root
        result = TreeNode(0)
        if root.val <val:
            result = self.searchBST(root.right,val)
        if root.val >val:
            result =self.searchBST(root.left,val)
        return result
3.2.2 迭代法
# 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]:
        while root:
            if root.val>val:
                root = root.left
            elif root.val<val:
                root = root.right
            else:
                return root

3.3 本题小结

  1. 这道题首先是二叉搜索树的概念,左子树永远比根节点小,右子树永远比根节点大,根据这个思路往下写就行了
  2. 对于递归而言,如果知道这个,就容易,不过目前没彻底弄明白为什么要赋值result
  3. 递归法,就是听了会了,写的时候懵了,看题解的时候彻底会了,有点聪明但不多哈哈哈哈哈哈哈

4 leetcode98.验证二叉搜索树

题目链接:98. 验证二叉搜索树 - 力扣(LeetCode)

文章链接:代码随想录

视频链接:你对二叉搜索树了解的还不够! | LeetCode:98.验证二叉搜索树_哔哩哔哩_bilibili

思路:哈哈哈哈哈哈,开始想的是如果左子树和右子树的值满足二叉搜索树的情况,就可以返回True;结果写的时候,根本不会写,,

4.1 自己的代码

写了一句有超级大问题的代码

if root.val>root.left.val and root.val<root.right.val:
            return True
        result = TreeNode(0)

这里问题出在,只判断了他的左右节点,没有判断左子树和右子树,二叉树的概念有一些混淆!!!!

4.2 视频后的思路

看完了,但是怎么说呢,感觉还是有一点点难度,写起来有一点不知如何下手的感觉,,

重点:判断这个问题的时候,其实很好的一个想法就是使用中序遍历,因为这样可以保证出来的值是从小到大排序的一个过程

4.2.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 isValidBST(self, root: Optional[TreeNode]) -> bool:
        self.vec = []
        self.traversal(root)
        for i in range(len(self.vec)-1):
            if self.vec[i]>=self.vec[i+1]:
                return False
        return True
    def traversal(self,node):
        if node ==None:
            return True
        self.traversal(node.left)
        self.vec.append(node.val)
        self.traversal(node.right)
4.2.2 使用极小值的方法

定义一个极值,然后就是在中序的时候比较当前值和极值的关系,做一个返回的操作

# 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.maxval = float('-inf')
    def isValidBST(self, root: Optional[TreeNode]) -> bool:
        if root == None:
            return True
        left = self.isValidBST(root.left)
        if root.val>self.maxval:
            self.maxval = root.val
        else:
            return False
        right = self.isValidBST(root.right)
        return left and right
4.2.3 双指针的方法

这种方法就是定义一个前指针,然后比较前一个值和当前值的关系,如果遇到了不符合的就返回

# 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.pre = None
    def isValidBST(self, root: Optional[TreeNode]) -> bool:
        if root == None:
            return True
        left = self.isValidBST(root.left)
        if self.pre !=None and self.pre.val>=root.val:
            return False
        self.pre = root
        right = self.isValidBST(root.right)
        return left and right

4.3 本题小结

  1. 本题的主要难点对我而言,就是上去思路就错了,其次分析二叉树的题目没有严格按照遍历顺序去思考,导致这个题目花费了挺多时间的
  2. 思路上的总结,首先,这个是验证,所以传入的是这个二叉树,终止条件找不正确的,然后第三部就是递归的内部逻辑,按照这个来就容易一些
  3. 记住使用的是中序遍历方法

5 今日小结

  1. 前两道题是对递归方法的一个总结吧,我觉得是,相比而言就是比较中规中矩的递归方法
  2. 后两道题是对二叉搜索树概念的掌握和理解,在写的过程越来越对这种概念理解的清晰了,题目思路也顺畅了很多
  3. 希望接下来我可以真的自己分析题目,感觉现在的代码都是看了视频才会,离开视频可能就不会了,,,
posted @ 2024-11-06 16:14  小方呀0524  阅读(8)  评论(0编辑  收藏  举报