📌  相关文章
📜  二叉树中最深的右叶节点 |迭代方法(1)

📅  最后修改于: 2023-12-03 15:06:19.892000             🧑  作者: Mango

二叉树中最深的右叶节点 - 迭代方法

简介

本篇介绍了一种迭代方法来寻找二叉树中最深的右叶节点。本方法避免了使用递归,使代码更具可读性。同时也可以应用于寻找二叉树中最深的叶节点(左右均可)。

解题思路

本题的难点在于如何找到最深的右叶节点。我们可以使用DFS(深度优先搜索)的思路,从根节点开始遍历整个二叉树。在遍历过程中,将当前节点的深度和该节点是否为右叶节点记录下来。如果当前节点不是叶节点,那么我们就将该节点的左右子节点加入到遍历队列中。

为了防止出现同深度的右叶节点,我们可以在每个深度的元素入队时,先将右子节点入队,这样右叶节点在同深度的元素出队时就会被最后访问到。

最后遍历完整个二叉树,可以得到二叉树中最深的右叶节点。如果二叉树为空,我们就返回空。如果二叉树只有一个节点,它本身就是最深的右叶节点。

代码实现
def findDeepestRightLeaf(root: TreeNode) -> TreeNode:
    if not root:
        return None

    deepest = None
    currDepth = -1

    stack = [(root, 0)]

    while stack:
        node, depth = stack.pop()

        if depth > currDepth:
            deepest = None
            currDepth = depth

        if not node.left and not node.right and depth == currDepth and (not deepest or deepest.right):
            deepest = node

        if node.right:
            stack.append((node.right, depth + 1))

        if node.left:
            stack.append((node.left, depth + 1))

    return deepest
代码解析

代码共有两个部分:初始化和迭代。

初始化

初始化过程中,我们需要定义三个变量:deepest、currDepth、和stack。

  • deepest:表示迄今为止最深的右叶节点。
  • currDepth:表示当前二叉树中最深的叶节点的深度。
  • stack:表示遍历二叉树的栈,存储了待遍历节点和它们的深度。

对于初始化部分的代码:

deepest = None
currDepth = -1
stack = [(root, 0)]

我们将deepest初始化为None,currDepth初始化为-1,因为我们一开始还没有找到最深的叶节点。栈中加入了根节点和初始深度0。

迭代

接下来我们进入迭代部分。进入while循环,只要stack不为空就持续迭代。在每次迭代中,我们弹出栈顶元素,分别判断它是否满足最深叶节点和右叶节点的条件。

node, depth = stack.pop()

对于每个节点,我们首先判断当前深度是否大于已知最深叶节点的深度。如果是,我们就将最深叶节点重置为None,并将currDepth更新为当前深度。

if depth > currDepth:
    deepest = None
    currDepth = depth

接下来,我们判断当前节点是否是叶节点,并且是否在当前最深深度中为右叶节点。如果是,我们就将该节点标记为最深叶节点。如果当前深度同已知最深的深度,那么我们就需要根据deepest记录的右叶节点是否存在选择是否更新deepest。

if not node.left and not node.right and depth == currDepth and (not deepest or deepest.right):
    deepest = node

最后,我们将节点的左右子节点按照右左顺序入栈。

if node.right:
    stack.append((node.right, depth + 1))

if node.left:
    stack.append((node.left, depth + 1))
总结

本篇介绍了一种利用DFS寻找二叉树中最深叶节点的方法。由于使用了栈来存储待访问节点,避免了使用递归,因此代码更易读懂。如果你仍然觉得代码仍不够直观,那么你可以将栈改为队列,使用BFS来访问节点,代码将会更加直观易懂。