您的位置:首页 > Web前端

剑指offer解题报告(Java版)——二叉树中和为某一值的路径 25

2015-04-30 10:12 537 查看
分析问题



首先需要明白路径的概念,路径是从根节点出发,一直到叶子节点,所形成的一条路径

所以我们寻找和为某一值的路径的时候,首先从根节点10出发,前序遍历二叉树,路径为10,5,4,发现和不为22,所以需要从4返回到5,然后再走7,发现和为22,记录下这条路径

然后再返回到5,再返回到10,再从10的右子树开始,到12,又记录下一条路径

发现这是一个栈的结构,所以我们考虑用一个栈来存储路径,另外我们需要一个结果来存储currentSum,用于与exceptedSum相比较

解决问题

public void findPath(BinaryTreeNode root, int expectedSum,

Stack<Integer> path, int currentSum) {

if (root == null)

return;

currentSum += root.data;

path.push(root.data);

boolean isLeaf = root.leftNode == null && root.rightNode == null;

if (isLeaf) {

if (currentSum == expectedSum) {

System.out.println("A path is");

for (int i : path)

System.out.print(i+" ");

System.out.println();

}

} else {

if (root.leftNode != null) {

findPath(root.leftNode, expectedSum, path, currentSum);

}

if (root.rightNode != null) {

findPath(root.rightNode, expectedSum, path, currentSum);

}

}

currentSum -= root.data;

path.pop();

}

测试代码

MySo2 mySo2=new MySo2();

Stack path=new Stack<>();

int currentSum=0;

mySo2.findPath(root1, 22, path, currentSum);

首先创建一个stack用于存放路径,作为参数传入findpath中,另外也将currentSum作为参数传入

在findPath函数中,首先判断一下root是否为空,为空的话就没什么好玩儿的了

不为空,那么将currentSum加上root的值,表明现在的Sum,将root的值压入栈中,这里取了个巧,只压入了root的data值,而不是压入的节点

因为这里仅仅需要实现的一个功能是在递归返回上一层的时候,将节点从路径中删除,而返回上一层节点在递归的时候就已经实现了

对于路径来说,需要判断是否抵达叶子节点,叶子节点的定义是没有左右孩子,这里将对节点的判断用个boolean值来替代,使得代码简洁一些

如果是叶子节点,判断一下currentSum和exceptedSum是否相等,如果相等,将路径打印出来

如果不是叶子节点,那么就需要前序遍历递归到左子树,然后返回到上一层,递归到右子树

右子树返回的时候,需要将栈弹出,说明要将这个节点从路径中删除

实例说明

说一下上述树的递归过程吧,首先传入10,currentSum=10,将10压入栈中,10不是叶子节点,有左孩子5,进入到左子树,也就是递归的下一层,这时候的参数root=5,exceptedSum一直没变是22,这里后面不再说了,path中有10,currentSum=10,传进来之后,5不为空(其实这里每次都要判读一下不是很好,可以优化),currentSum要加上这个5,成为15,5压入栈中,5也不是叶子节点,继续进入左子树,为4,currentSum加上4,为19,4压入栈中,4是叶子节点,但是19不等于22,这里不会进入else了,就直接currentSum减去4,并将栈中的4弹出,此时栈中只有10和5,进入到5的右子树,同样的判断,和为22,打印出来,然后弹出7,返回到上一层,由于上一层已经执行到进入右子树那条语句,也就是if (root.rightNode != null) findPath(root.rightNode, expectedSum, path, currentSum);所以下一条应该执行的语句就是currentSum减去5,将5弹出,此时再返回上一层,也就是现在栈中只有10,由于在10这一层,只执行到

if (root.leftNode != null) findPath(root.leftNode, expectedSum, path, currentSum);这条语句,接下来应该执行进入右子树的语句了,接下来也就没什么好说的了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: