java二叉树路径和等于指定值_算法系列之从二叉树中和等于”某个值“的路径...

题目来源 《剑指offer》 作者何海涛

01 题目描述

输入一个二叉树和一个整数,输出二叉树中所有的和为这个整数的路径。路径:从二叉树的根节点开始一直到叶子节点就是树的一条路径。

如树

de82e95c814dfe6fd48edb54f3cf7126.png

8,6,5是其中一条路径。

对于整数21,那么8,6,7是我们要找的目标路径。

02 解题

树结构如下图,我们要找路径之和等于22的树的路径。

8acf750cfd65362bbb78d872422b6ec7.png

树结构

我们用肉眼可观测到的两条是 10,5,7。和10,12。

那么用程序怎么找呢,我们从根节点开始遍历,遍历它每一条路径的和与目标值22相同时输出路径。

遍历过程如下:

(1)遍历第一条路径 10,5,4,值为19 不等于22

0964a8f89d20169ce06c88bc1992c416.gif

(2)由于第一条路径的值,不等于目标路径,将4回退到上一层5,访问5的右孩子节点。

到达另外一条路径,路径的值为10,5,7 之和为目标值22。输出。

2fad1a0e5a07f450dc1d15afb56fd580.gif

(3)第二条路径,7无左右孩子节点,回退5。5左右孩子节点已经访问完毕,回退到根节点10。

f44d3f60ed6ad49646d6deb0e9229423.gif

(4)由于10的右孩子节点还没有访问,访问右孩子节点12。到达叶子节点,路径10,12的和为22 。与目标值相等。输出

f8b46d702dad59d864138587439e84f4.gif

总的得出两组结果。

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;}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值