【leetcode刷刷】104.二叉树的最大深度 、111.二叉树的最小深度 、222.完全二叉树的节点个数

104. 二叉树的最大深度

  1. 自己用递归和迭代都写了一下,虽然做出来了,但感觉递归还是有点不熟练
  2. 递归的时候,确定参数和返回值:本题需要的是树的深度,知道子树的深度自然可以知道树的深度就是子树+1,所以返回树的深度。参数的话就是子树的顶端节点。
  3. 写迭代的时候没有用层序遍历,直接用的栈,相当于dfs了。就是需要把(node, depth)一起压入栈,读出来的时候处理最大值。
  4. 写层序遍历的话,就比较符合常理,因为是一层一层的,适合算深度。
class Solution:
    def maxDepth(self, root: Optional[TreeNode]) -> int:
        if not root:
            return 0

        # 层序遍历
        q = collections.deque()
        q.append(root)
        maxDepth = 0
        while(q):
            maxDepth += 1
            for i in range(len(q)):
                node = q.popleft()
                if node.left: q.append(node.left)
                if node.right: q.append(node.right)
        return maxDepth

        # 迭代
        stack = [(root, 1)]
        maxDepth = 1
        while(stack):
            node, depth = stack.pop()
            maxDepth = max(maxDepth, depth)
            if node.left:
                stack.append((node.left, depth+1))
            if node.right:
                stack.append((node.right, depth+1))
        return maxDepth

        # 递归
        return self.dfs(root) + 1

    def dfs(self, root):
        # 参数:节点,返回树的深度
        # 终止条件
        if not root:
            return 0
        return max(self.dfs(root.left)+1, self.dfs(root.right)+1)
             

111. 二叉树的最小深度

  1. 递归法,一开始写的时候确实没有理解好最小深度的意思。是根节点到叶子节点的最小距离,如果直接按照max的思路来做的话,在左节点或右节点一个是NULL的时候输出的结果,但实际上应该是左右都空的时候输出。因此在写的时候,左右只有一个为空需要单独列出来
  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 minDepth(self, root: Optional[TreeNode]) -> int:
        # 迭代法
        if not root: return 0
        q = collections.deque()
        q.append(root)
        depth = 0
        while(q):
            depth += 1
            for i in range(len(q)):
                node = q.popleft()
                if not node.left and not node.right:  # 当遍历到的是叶子节点的时候,输出现在的深度
                    return depth
                if node.left: q.append(node.left)
                if node.right: q.append(node.right)

        # 递归法
        # 返回二叉树的最小深度。参数是顶端节点。
        # 最近叶子节点。
        if not root:
            return 0
        if not root.left and not root.right:
            return 1
        left = self.minDepth(root.left)
        right = self.minDepth(root.right)
        if not root.left:
            return right + 1
        if not root.right:
            return left + 1
        return min(left, right) + 1

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

  1. 普通二叉树的话,就是遍历,dfs和bfs都可以,时间关系没有写
  2. 想了好久完全二叉树怎么算,原来是这么递归的。第一次想不到。通过左深度和右深度是否相等来判断子树是不是完全二叉树,完全二叉树就可以用公式计算。
class Solution:
    def countNodes(self, root: Optional[TreeNode]) -> int:
        # 遍历都可以求节点个数吧

        # 进阶:遍历树来统计节点是一种时间复杂度为 O(n) 的简单解决方案。你可以设计一个更快的算法吗?
        # 完全二叉树的话,只要一直看左节点,到最后一行再遍历
        if not root: return 0
        
        # 终止条件
        left_depth = 1
        left = root.left
        right_depth = 1
        right = root.right
        while(left):
            left_depth += 1
            left = left.left
        while(right):
            right_depth += 1
            right = right.right
        if left_depth == right_depth: return 2 ** (left_depth) - 1

        return self.countNodes(root.left) + self.countNodes(root.right) + 1
                            
  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值