vlambda博客
学习文章列表

【阿里高频题】动画讲解二叉树深度优先遍历

在 中,我们学习了二叉树的层次遍历,这次我们要学习的是二叉树的深度优先遍历。这是两种非常经典的二叉树遍历方式,可以说,属于面试大厂时闭着眼都要能写出来的方式。

1 例题描述

给当一个二叉树和一个数S,验证是否存在一个从root到leaf的路径,路径上元素的和恰好等于S。

例子1

比如S=10,下图中就存在 1-3-6这条路径。

例子2

再比如S=23,下图中是存在 12-1-10这条路径的。

2 问题分析

因为我们要寻找的是从root到leaf的路径,显然可以使用深度优先搜索(DFS)来完成任务。

利用DFS来递归访问一个二叉树时,我们是从根节点开始,然后在每一步中,分别递归地访问当前节点的左右子节点。

具体到今天这道题,我们可以这么做(后面有动画展示):

  • 从root节点开始进行DFS遍历
  • 如果当前节点不是leaf节点,做两件事:
    • 更新S值,将S值减去当前节点的值,作为新的S值,即S = S - node.value
    • 递归访问该节点的左右子节点,同时传入更新后的S值
  • 在每一步中,如果当前节点是leaf节点,并且节点的值等于传过来的S值,此时,我们就找到一条满足条件的路径!返回true即可。
  • 如果当前节点是leaf节点,但是节点的值不等于传入的S,则说明该从root到该leaf的路径不符合要求,返回false即可。

例子2为例,整个算法过程如下所示:

3 代码实现

class TreeNode:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right


def has_path(root, sum):
if root is None:
return False

# 当前节点是leaf节点,
# 并且它的节点值等于传过来的S值,
# 我们就找到了一个路径
if root.val == sum and root.left is None and root.right is None:
return True

# 递归遍历左右子树
# 当任何一棵子树返回true时
# 就返回true给上级调用
return has_path(root.left, sum - root.val) or has_path(root.right, sum - root.val)

4 思考题

如何找到所有满足条件的路径呢?且听下回分解。



往期精彩回顾