1. 题目
输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径。从树的根节点开始往下一直到叶节点所经过的节点形成一条路径。二叉树节点的定义如下:
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
}
python 版
class BinaryTreeNode(object):
def __init__(self, value, left=None, right=None):
self.value = value
self.left = left
self.right = right
2. 解题思路
需要记住的是,遇到不会的就举例子,找规律,得出逻辑。
读题
- 路径是从根节点一直到叶节点;
- 要找到符合条件的所有路径。
也就是说,此节点必须是叶节点且路径之和为num的时候,这条路径才是符合条件的。
首先考虑递归,递归让我们理解起来更清楚。
从根节点开始,根节点的值若小于num,那么继续往根节点的下一级寻找,如此递推。既然要使用递归,那么递归的基线条件是什么呢?
3. 代码实现
3.1 递归版
def find_path(root, expected_sum):
"""
:param root: 二叉树的根节点
:param expected_sum: 整数,路径上节点值之和
"""
if not root:
return
path = [] # 记录树的路径
current_sum = 0 # 当前path中路径中的节点值之和
find_one_path(root, expected_sum, path, current_sum)
def find_one_path(root, expected_sum, path, current_sum):
"""
:param root: 二叉树的根节点
:param expected_sum: 整数,路径上节点值之和
:param path: 记录节点路径
:param current_sum: 当前路径中节点值之和
"""
# 将当前的根节点加入path的尾部,并且此时路径之和为原来和加上当前根节点的值
current_sum += root.value
path.append(root.value)
# 路径之和等于输入的整数,且此节点为叶节点点(既无左子节点又无右子节点)
if current_sum == expected_sum and not root.left and not root.right:
# 那么此时应该从前到后打印path中的元素,这就是我们走过的路径。
print("发现一条路径: ")
for i in path:
print("{}\t".format(i))
print("\n")
# 如果不是叶节点,则遍历它的子节点
if root.left:
find_one_path(root.left, expected_sum, path, current_sum)
if root.right:
find_one_path(root.right, expected_sum, path, current_sum)
# 如果已经是叶节点了,但是路径之后不等于我们期望的值,那么往后退一步,返回父节点
path.pop()
4. 总结
其实本题的遍历顺序用的是前序遍历。总之,通过举例子,找出规律和逻辑。然后在考虑各种边界条件,增强代码的鲁棒性。
5. 参考文献
[1] 剑指offer丛书