104.二叉树的最大深度

# 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 maxDepth0(self, root: Optional[TreeNode]) -> int:
        if root is None:
            return 0
        return max(self.maxDepth(root.left),self.maxDepth(root.right))+1 
    def maxDepth1 (self, root: Optional[TreeNode]) -> int:
        if root is None:
            return 0
        #stack定义
        stack=[]
        stack.append((root,1))
        depth =0
        while stack: 
            temp =stack.pop()
            depth =max(depth,temp[1])
            if temp[0].right:
                stack.append((temp[0].right,temp[1]+1))
            if temp[0].left:
                stack.append((temp[0].left,temp[1]+1))
        return depth      
    def maxDepth (self, root: Optional[TreeNode]) -> int:
        if root is None:
            return 0
        #quene 
        quene=deque()
        quene.append((root,1))
        depth=0
        while quene:
            temp=quene.popleft()
            depth=max(depth,temp[1])
            if temp[0].left:
                quene.append((temp[0].left,temp[1]+1))
            if temp[0].right:
                quene.append((temp[0].right,temp[1]+1))
        return depth    
# 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 maxDepth0(self, root: Optional[TreeNode]) -> int:
        if root is None:
            return 0
        return max(self.maxDepth(root.left),self.maxDepth(root.right))+1 
    def maxDepth1 (self, root: Optional[TreeNode]) -> int:
        if root is None:
            return 0
        #stack定义
        stack=[]
        stack.append((root,1))
        depth =0
        while stack: 
            temp =stack.pop()
            depth =max(depth,temp[1])
            if temp[0].right:
                stack.append((temp[0].right,temp[1]+1))
            if temp[0].left:
                stack.append((temp[0].left,temp[1]+1))
        return depth      
    def maxDepth (self, root: Optional[TreeNode]) -> int:
        if root is None:
            return 0
        #quene 
        quene=deque()
        quene.append((root,1))
        depth=0
        while quene:
            temp=quene.popleft()
            depth=max(depth,temp[1])
            if temp[0].left:
                quene.append((temp[0].left,temp[1]+1))
            if temp[0].right:
                quene.append((temp[0].right,temp[1]+1))
        return depth    
    # 方法一:递归 (Recursion) - 深度优先搜索 (DFS)
    def maxDepth00(self, root: Optional[TreeNode]) -> int:
        """
        使用递归计算二叉树的最大深度。
        时间复杂度: O(N),其中 N 是节点数,因为每个节点恰好访问一次。
        空间复杂度: O(H),其中 H 是树的高度。最坏情况下(树退化成链表)为 O(N),
                  最好情况下(完全平衡树)为 O(log N),这是递归调用栈所需的空间。
        """
        # 基线条件:如果节点为空 (root is None),表示到达了叶子节点的子节点或空树,深度为 0。
        if root is None:
            return 0

        # 递归步骤:
        # 树的最大深度等于其左右子树中较深者的深度,再加上当前节点本身这一层 ( + 1)。
        # 递归调用自身来获取左子树的最大深度。
        left_depth = self.maxDepth0(root.left) # 注意:这里递归调用自身 maxDepth0
        # 递归调用自身来获取右子树的最大深度。
        right_depth = self.maxDepth0(root.right) # 注意:这里递归调用自身 maxDepth0

        # 返回左右子树深度的最大值,并加上当前层的 1。
        return max(left_depth, right_depth) + 1

    # 方法二:迭代深度优先搜索 (Iterative DFS) - 使用栈 (Stack)
    def maxDepth11 (self, root: Optional[TreeNode]) -> int:
        """
        使用迭代和栈 (Stack) 实现深度优先搜索来计算最大深度。
        时间复杂度: O(N),每个节点入栈出栈一次。
        空间复杂度: O(H),栈所需的最大空间取决于树的高度。最坏情况 O(N),最好情况 O(log N)。
        """
        # 如果根节点为空,树的深度为 0。
        if root is None:
            return 0

        # 定义一个栈,用于存储待访问的节点及其对应的深度。
        # 栈中存储的是元组 (node, depth)。
        stack = []
        # 将根节点和其深度 1 压入栈中。
        stack.append((root, 1))

        # 初始化最大深度为 0。
        depth = 0

        # 当栈不为空时,持续循环。
        while stack:
            # 从栈顶弹出一个元素 (节点, 当前深度)。栈是 LIFO (后进先出)。
            temp = stack.pop()
            node, current_depth = temp[0], temp[1] # 解包元组

            # 更新目前为止发现的最大深度。
            depth = max(depth, current_depth)

            # 检查当前节点的子节点,并将它们压入栈中,深度加 1。
            # 先压右子节点,再压左子节点,这样下次循环会优先处理左子节点(DFS 特点)。
            # (对于求最大深度,左右顺序不影响最终结果)
            if node.right:
                stack.append((node.right, current_depth + 1))
            if node.left:
                stack.append((node.left, current_depth + 1))

        # 循环结束后,depth 变量存储了遍历过程中遇到的最大深度。
        return depth

    # 方法三:迭代广度优先搜索 (Iterative BFS) - 使用队列 (Queue)
    def maxDepth22 (self, root: Optional[TreeNode]) -> int:
        """
        使用迭代和队列 (Queue) 实现广度优先搜索来计算最大深度。
        时间复杂度: O(N),每个节点入队出队一次。
        空间复杂度: O(W),其中 W 是树的最大宽度。最坏情况下(完美二叉树的最后一层)可能达到 O(N)。
        """
        # 如果根节点为空,树的深度为 0。
        if root is None:
            return 0

        # 定义一个双端队列 (deque) 作为 FIFO (先进先出) 队列。
        queue = deque()
        # 将根节点和其深度 1 加入队列。
        queue.append((root, 1))

        # 初始化最大深度为 0。
        depth = 0

        # 当队列不为空时,持续循环。
        while queue:
            # 从队列左侧(队首)取出一个元素 (节点, 当前深度)。
            temp = queue.popleft()
            node, current_depth = temp[0], temp[1] # 解包元组

            # 更新目前为止发现的最大深度。
            # 在 BFS 中,因为是按层遍历,最后处理完的节点一定在最深层,
            # 所以也可以只在循环外返回最后一层的 current_depth。
            # 但这种写法 (不断更新 max) 对于 DFS 和 BFS 都适用。
            depth = max(depth, current_depth)

            # 检查当前节点的子节点,并将它们加入队列,深度加 1。
            # BFS 通常先处理左子节点再处理右子节点。
            if node.left:
                queue.append((node.left, current_depth + 1))
            if node.right:
                queue.append((node.right, current_depth + 1))

        # 循环结束后,depth 变量存储了遍历过程中遇到的最大深度。
        return depth

# 注意:
# 1. 在实际使用中,你需要确保 TreeNode 类已定义,并且导入了 Optional 和 deque。
# 2. 在 maxDepth0 的递归调用中,应该调用 self.maxDepth0 而不是 self.maxDepth,以保持函数独立性(除非你有意混合调用)。假设这是一个笔误,我在注释中指出了这一点,但未修改原始代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值