题目来源 《剑指offer》 作者何海涛
01 题目描述
输入一个二叉树和一个整数,输出二叉树中所有的和为这个整数的路径。路径:从二叉树的根节点开始一直到叶子节点就是树的一条路径。
如树
8,6,5是其中一条路径。
对于整数21,那么8,6,7是我们要找的目标路径。
02 解题
树结构如下图,我们要找路径之和等于22的树的路径。
我们用肉眼可观测到的两条是 10,5,7。和10,12。
那么用程序怎么找呢,我们从根节点开始遍历,遍历它每一条路径的和与目标值22相同时输出路径。
遍历过程如下:
(1)遍历第一条路径 10,5,4,值为19 不等于22
(2)由于第一条路径的值,不等于目标路径,将4回退到上一层5,访问5的右孩子节点。
到达另外一条路径,路径的值为10,5,7 之和为目标值22。输出。
(3)第二条路径,7无左右孩子节点,回退5。5左右孩子节点已经访问完毕,回退到根节点10。
(4)由于10的右孩子节点还没有访问,访问右孩子节点12。到达叶子节点,路径10,12的和为22 。与目标值相等。输出
总的得出两组结果。
03 总结 & 代码
1.首先要深度优先遍历二叉树,遍历顺序,根节点,左孩子节点,右孩子节点。
2.在遍历每条路径时,记录当前路径的和,到达叶子节点时,与目标值对比。相等输出。
3.回退选择其他路径。直到所有的路径都被遍历完。
代码实现(这里用的是递归的方式)
public static void findPath(BinaryTreeNode treeNode, int target) { if (treeNode == null) { return; } Stack pathStack = new Stack<>(); int currentSum = 0; findPath(treeNode, target, pathStack, currentSum);}public static void findPath(BinaryTreeNode treeNode, int target, Stack pathStack, int currentSum) { currentSum += treeNode.value; pathStack.push(treeNode); // 1.是叶子节点 if (treeNode.leftChild == null && treeNode.rightChild == null) { if (target == currentSum) { printArray(pathStack); } } // 2.不是叶子节点 if (treeNode.leftChild != null && currentSum < target) { findPath(treeNode.leftChild, target, pathStack, currentSum); } if (treeNode.rightChild != null && currentSum < target) { findPath(treeNode.rightChild, target, pathStack, currentSum); } // 是叶子节点,或者左右节点已经都被访问了,回退 pathStack.pop();}public static void printArray(Stack pathStack) { Object[] result = pathStack.toArray(); for (int i = 0, length = result.length; i < length; i ++) { System.out.print(((BinaryTreeNode)result[i]).value + " "); } System.out.println();}
测试代码
public static void main(String[] args) { BinaryTreeNode treeNode7 = new BinaryTreeNode(null, null, 7); BinaryTreeNode treeNode6 = new BinaryTreeNode(null, null, 6); BinaryTreeNode treeNode5 = new BinaryTreeNode(treeNode7, null, 5); BinaryTreeNode treeNode4 = new BinaryTreeNode(null, null, 4); BinaryTreeNode treeNode3 = new BinaryTreeNode(treeNode4, null, 3); BinaryTreeNode treeNode2 = new BinaryTreeNode(treeNode5, treeNode6, 2); BinaryTreeNode treeNode1 = new BinaryTreeNode(treeNode3, null, 1); BinaryTreeNode treeNode = new BinaryTreeNode(treeNode1, treeNode2, 0); /** * 0 * 1 2 * 3 4 5 6 * 7 */ findPath(treeNode, 5); /** * 0 * 1 2 * 3 5 6 *4 7 */// findPath(treeNode, 8); findPath(null, 8); }
树结构
class BinaryTreeNode { int value; BinaryTreeNode leftChild; BinaryTreeNode rightChild;}