📅  最后修改于: 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 = 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来访问节点,代码将会更加直观易懂。