LeetCode2:20 二叉树100 104 110 124

20有效的括号

给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。

有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。

示例 1:		示例 2:			示例 3:		示例 4:			示例 5:
输入: "()"	输入: "()[]{}"	输入: "(]"	输入: "([)]"	输入: "{[]}"
输出: true	输出: true		输出: false	输出: false		输出: true
class Solution:
    def isValid(self, s: str) -> bool:
        dic = {"{" :"}", "[" :"]", "(" :")",'?': '?'}
        stack = ["?"]
        for c in s:
            if c in dic:
                stack.append(c)
            elif dic[stack.pop()] != c:
                return False
        return len(stack) == 1
# 栈先入后出特点恰好与本题括号排序特点一致
# 栈 stack 为空: 此时 stack.pop() 操作会报错;因此,我们采
#  用一个取巧方法,给 stack 赋初值 ?? 

二叉树

前序遍历:先访问根节点,再前序遍历左子树,再前序遍历右子树 (根左右
中序遍历:先中序遍历左子树,再访问根节点,再中序遍历右子树 (左根右)
后序遍历:先后序遍历左子树,再后序遍历右子树,再访问根节点(左右根
在这里插入图片描述
在这里插入图片描述

100. 相同的树

给定两个二叉树,编写一个函数来检验它们是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

示例 1:
输入:       1         1
          / \       / \
         2   3     2   3

        [1,2,3],   [1,2,3]
输出: true

示例 2:
输入:      1          1
          /           \
         2             2

        [1,2],     [1,null,2]
输出: false

示例 3:
输入:       1         1
          / \       / \
         2   1     1   2
        [1,2,1],   [1,1,2]
输出: false
class Solution:
    def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
        if p == None and q == None:
            return True
        elif p == None or q == None:
            return False
        elif p.val != q.val:
            return False
        else:
             return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)

104. 二叉树的最大深度

给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。

示例:
给定二叉树 [3,9,20,null,null,15,7]3
   / \
  9  20
    /  \
   15   7
返回它的最大深度 3

答案:

class Solution:
    def maxDepth(self, root: TreeNode) -> int:
        if not root:
            return 0
        return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right))

110. 平衡二叉树

给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。

示例 1:

给定二叉树 [3,9,20,null,null,15,7]

    3
   / \
  9  20
    /  \
   15   7
返回 true 。

示例 2:

给定二叉树 [1,2,2,3,3,null,null,4,4]

       1
      / \
     2   2
    / \
   3   3
  / \
 4   4
返回 false

自顶而下的
思路是构造一个获取当前节点最大深度的方法 depth(root) ,通过比较此子树的左右子树的最大高度差abs(depth(root.left) - depth(root.right)),来判断此子树是否是二叉平衡树。若树的所有子树都平衡时,此树才平衡。

算法流程:
isBalanced(root) :判断树 root 是否平衡

特例处理: 若树根节点 root 为空,则直接返回 truetrue ;
返回值: 所有子树都需要满足平衡树性质,因此以下三者使用与逻辑 && 连接;
abs(self.depth(root.left) - self.depth(root.right)) <= 1 :判断 当前子树 是否是平衡树;
self.isBalanced(root.left) : 先序遍历递归,判断 当前子树的左子树 是否是平衡树;
self.isBalanced(root.right) : 先序遍历递归,判断 当前子树的右子树 是否是平衡树;
depth(root) : 计算树 root 的最大高度

终止条件: 当 root 为空,即越过叶子节点,则返回高度 00 ;
返回值: 返回左 / 右子树的最大高度加 11 。

class Solution:
    def isBalanced(self, root: TreeNode) -> bool:
        def depth(root):
            """求当前节点的深度
            Args: root: 节点
            Returns:返回节点深度
            """
            # 节点为空,返回高度 0
            if not root:
                return 0
            # 否则返回左右子树最大高度值 +1
            return max(depth(root.left), depth(root.right)) + 1
        # 根节点为空,直接返回 True
        if not root:
            return True

        # 否则递归判断
        # 1. 当前子树是否平衡
        # 2. 当前子树左子树是否平衡
        # 3. 当前子树右子树是否平衡
        return abs(depth(root.left)-depth(root.right)) <= 1 and self.isBalanced(root.left) and self.isBalanced(root.right)

124. 二叉树中的最大路径和

给定一个非空二叉树,返回其最大路径和。
本题中,路径被定义为一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。

示例 1:
输入:[1,2,3]
       1
      / \
     2   3
输出:6

示例 2:
输入:[-10,9,20,null,null,15,7]
   -10
   / \
  9  20
    /  \
   15   7
输出:42
class Solution:
    def maxPathSum(self, root: TreeNode) -> int:
        self.res = float("-inf")
        # 我们先定义一个全局变量res=flaot("-inf")来存储全局的最大值,
        # 也就是我们需要返回的值
        def helper(root):
            if not root: 
                return 0
            # 左边最大值
            left = helper(root.left)
            # 右边最大值
            right = helper(root.right)
            # 和全局变量比较
            self.res = max(left + right + root.val, self.res)
            # >0 说明都能使路径变大
            return max(0, max(left,  right) + root.val)
        helper(root)
        return self.res

我们用题目的示例来描述一下这个算法过程:(理解如何递归很关键)


1. 从 dfs(-10) 开始, 
        1.1  dfs(9): 
            1.1.1 左孩子为空;贡献为 0
            1.1.2 右孩子为空,贡献为 0
            1.1.3 更新 res = max (-∞,(9 + 0 + 0)) = 9
            1.1.4 返回 dfs(9) = 9 + max(左孩子贡献,右孩子贡献)) = 9

        1.2  dfs(20)
            1.2.1 dfs(15):

                1.2.1.1 左孩子为空;贡献为0
                1.2.1.2 右孩子为空,贡献为0
                1.2.1.3 更新 res = max(9, 15 + 0 + 0) = 15
                1.2.1.4 返回 dfs(15) = 15 + 0 = 15

            1.2.2  dfs(7):

                1.2.2.1 左孩子为空;贡献为 0
                1.2.2.2 右孩子为空,贡献为 0
                1.2.2.3 更新 res = max(15, 7 + 0 + 0) = 15
                1.2.2.4 返回 dfs(7) = 7 + 0 = 7

            1.2.3  更新 res = max (15, 20 + dfs(15) + dfs(7) ) = 42
            1.2.4  返回dfs(20) = 20 + max(15, 7) = 35

        1.3 更新 res = max(42, -10 + dfs(9) + dfs(20) ) = max(42, 34) = 42 
        1.4 返回 dfs(-10) = -10 + max(9, 35) = 25 (当然这一步就没啥用了,已经有最终res)
	所以最大路径和 res = 42 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值