ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

leetcode(11)二叉树的属性系列题目

2022-05-15 14:33:22  阅读:143  来源: 互联网

标签:11 right return res self 节点 二叉树 root leetcode


104. 二叉树的最大深度

递归法
可以使用前序遍历(中左右),也可以使用后序遍历(左右中),使用前序求的就是深度,使用后序求的是高度。
而根节点的高度就是二叉树的最大深度

class Solution:
    def maxDepth(self, root: Optional[TreeNode]) -> int:
        return self.getHeight(root)
    
    def getHeight(self, root):
        if not root:
            return 0
        leftHeight = self.getHeight(root.left)
        rightHeight = self.getHeight(root.right)
        return max(leftHeight, rightHeight) + 1

111. 二叉树的最小深度

递归法

class Solution:
    def minDepth(self, root: TreeNode) -> int:
        if not root:
            return 0
        if not root.left and not root.right:
            return 1
        res = float('inf')
        if root.left:
            res = min(res, self.minDepth(root.left))
        if root.right:
            res = min(res, self.minDepth(root.right))
        return res + 1

222. 完全二叉树的节点个数

迭代法,按照普通二叉树的方法

class Solution:
    def countNodes(self, root: TreeNode) -> int:
        if not root:
            return 0
        res = 0
        
        from collections import deque
        que = deque([root])

        while que:
            size = len(que)
            for _ in range(size):
                cur = que.popleft()
                if cur.left:
                    que.append(cur.left)
                if cur.right:
                    que.append(cur.right)
                res += 1
        return res

递归法,利用完全二叉树的性质,求深度
只有两种情况:

  • 情况一:就是满二叉树,可以直接用 2^树深度 - 1 来计算,注意这里根节点深度为1。

  • 情况二:最后一层叶子节点没有满,分别递归左孩子,和右孩子,递归到某一深度一定会有左孩子或者右孩子为满二叉树,然后依然可以按照情况1来计算。

class Solution:
    def countNodes(self, root: TreeNode) -> int:
        if not root:
            return 0
        
        left = root.left
        right = root.right
        #这里初始为0是有目的的,为了下面求指数方便
        leftHeight = 0
        rightHeight = 0
        #求左子树深度
        while left:
            left = left.left
            leftHeight += 1
        #求右子树深度
        while right:
            right = right.right
            rightHeight += 1

        if leftHeight == rightHeight:
            return (2 << leftHeight) - 1  #注意(2<<1) 相当于2^2,所以leftHeight初始为0
        
        return self.countNodes(root.left) + self.countNodes(root.right) + 1

110. 平衡二叉树

  • 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数。
  • 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数。
    求深度适合用前序遍历,而求高度适合用后序遍历。

    递归法,后序遍历
class Solution:
    def isBalanced(self, root: TreeNode) -> bool:
        if self.getHeight(root) != -1:
            return True
        else:
            return False
        
    def getHeight(self, root):
        if not root:
            return 0
        leftHeight = self.getHeight(root.left)
        rightHeight = self.getHeight(root.right)
        if leftHeight == -1 or rightHeight == -1 or abs(leftHeight - rightHeight) >1:
            return -1
        else:
            return max(leftHeight, rightHeight) + 1

257. 二叉树的所有路径

需要前序遍历,这样才方便让父节点指向孩子节点,找到对应的路径。

在这道题目中将第一次涉及到回溯,因为我们要把路径记录下来,需要回溯来回退一一个路径在进入另一个路径。
递归法+隐形回溯

class Solution:
    def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
        if not root:
            return []
        path = ''
        res = []
        self.traversal(root, path, res)
        return res
    
    def traversal(self, root, path, res):
        path += str(root.val)
        # 若当前节点为leave,直接输出
        if not root.left and not root.right:
            res.append(path)
        if root.left:
            self.traversal(root.left, path + '->', res)  # + '->' 是隐藏回溯
        if root.right:
            self.traversal(root.right, path + '->', res)

543. 二叉树的直径

注意:一条路径的长度为该路径经过的节点数减一,所以求直径(即求路径长度的最大值)等价于求路径经过节点数的最大值减一
而任意一条路径均可以被看作由某个节点为起点,从其左儿子和右儿子向下遍历的路径拼接得到

class Solution:
    def diameterOfBinaryTree(self, root: Optional[TreeNode]) -> int:
        self.res = 0  # 0或1都可以
        def depth(root):
            # 访问到空节点了,返回0
            if not root:
                return 0
            # 左儿子为根的子树的深度
            leftDep = depth(root.left)
            # 右儿子为根的子树的深度
            rightDep = depth(root.right)
            # 计算d_node即L+R+1 并更新res
            self.res = max(self.res, leftDep + rightDep + 1)
            # 返回该节点为根的子树的深度
            return max(leftDep, rightDep) + 1
        depth(root)
        return self.res - 1

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

注意:与543. 二叉树的直径 的区别是注意节点值为负的情况

class Solution:
    def __init__(self):
        self.maxSum = float('-inf')

    def maxPathSum(self, root: Optional[TreeNode]) -> int:
        def maxGain(root):
            if not root:
                return 0
            # 递归计算左右子节点的最大贡献值
            # 只有在最大贡献值大于 0 时,才会选取对应子节点
            leftGain = max(maxGain(root.left), 0)
            rightGain = max(maxGain(root.right), 0)
            # 节点的最大路径和取决于该节点的值与该节点的左右子节点的最大贡献值
            curGain = root.val + leftGain + rightGain
            # 更新答案
            self.maxSum = max(self.maxSum, curGain)
             # 返回节点的最大贡献值
            return root.val + max(leftGain, rightGain)

        maxGain(root)
        return self.maxSum

标签:11,right,return,res,self,节点,二叉树,root,leetcode
来源: https://www.cnblogs.com/ttyangY77/p/16269869.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有