《剑指offer》——二叉树中和为某一值的路径

来源:互联网 发布:舆情软件 编辑:程序博客网 时间:2024/05/09 00:51

T:

题目描述
输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。

这道题从昨天晚上就在抠,抠了两个小时,最终代码写出来了,感觉有bug,没敢提交。

前一个小时,自己独立思考,寻找解题思路,也知道用递归,可如果使用递归?递归函数的定义该怎么设置?还是没思路。。。

后来在网上看到有博客中给出了相关的二叉树路径遍历知识点后,才开始有所顿悟。。。

先贴出链接: http://blog.csdn.net/sunmenggmail/article/details/7466635

这种问题是一类问题,可归为一类的其他问法包括:

  1. 给定一个二叉树,请遍历所有的路径;
  2. 找出和为某一个值的所有路径(不一定从根节点开始,中间某个节点也可以);
    1. 实际上,这种问法是对本题的推广,解决思路类似,只不过当前是限定在根节点,那么可以设置一个队列,类似于层次遍历的方式,把每个节点都当做一个根节点来重复此过程,就可逐个求出;
  3. 给出一个二叉树,问其叶子节点的个数?
  4. ……

不论是逐个打印,还是把所有结果都保存起来,都是这种结题思路,只不过在细节上略有变化。

比如: 如果要把所有路径都保存下来,那就多设置一个参数,记录每一条路径,入股该路径符合题目要求,就用一个全局变量把该路径添加进去。本题我就是用的次方法。

附:

当感觉递归函数无法一次性满足要求的诸多条件时,可以试试把条件放在参数中可好?
比如本题中,既然考虑累加之和,还要同时把符合条件的路径都保存下来,还要求出所有的路径,这种情况下,用参数来保存就是一种很好地方式,全局变量也可以。

我的code: 实际代码量不多,注释稍多一些。

    import java.util.ArrayList;    /**    public class TreeNode {        int val = 0;        TreeNode left = null;        TreeNode right = null;        public TreeNode(int val) {            this.val = val;        }    }    */    /**     * T: 二叉树中和为某一值的路径     *      * 题目描述      * 输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。     * 路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。     *      * data: 2015.11.29  20:13 ~ 2015.11.30  8:57     * @author SSS     *     */    public class Solution {        // 全局变量,用于存储得到的每一个路径        ArrayList<ArrayList<Integer>> resultsList = new ArrayList<ArrayList<Integer>>();        /**         * 建立额外一个函数,用来实现递归求解         * @param root         * @param target         * @return         */        public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {            ArrayList<Integer> pathList = new ArrayList<Integer>();            if (root == null) {                return resultsList;            }            int curSum = 0;            int index = 0;            int []path = new int[1000];            this.isTargetPath(root, target, curSum, path, index);            return this.resultsList;        }        /**         * 递归求解函数         * 思路很明白,把根节点到叶节点的路径上的值都加起来,         * 所以在递归的过程中,需要逐个累加,并且累加的同时,还要将沿途经过的节点值记录下来,         * 如何在递归函数中实现这一切功能呢?参数!!可用传参的方式解决         *          * @param eleNode   当前节点         * @param target    目标和         * @param curSum    当前已经累积到的和         * @param path  记录到当前的节点位置,经过的路径         * @param index 从根节点到当前节点为止,存的节点的数目         */        public void isTargetPath(TreeNode eleNode, int target, int curSum, int []path, int index) {            if (eleNode == null) {                return;            }            curSum += eleNode.val;            // 把该节点包含进去            path[index] = eleNode.val;            index ++;            // 当前已经是处于叶子节点,并且累计的和与target相等            if (curSum == target && eleNode.left == null && eleNode.right == null) {                // 将得到的结果放在外层结构中                ArrayList<Integer> pathList = new ArrayList<Integer>();                for (int i = 0; i < index; i++) {                    pathList.add(path[i]);                }                resultsList.add(pathList);                return;            }            // 该节点有左子节点,前提还是要curSum 小于 target,否则递归就没有意义了            if (curSum < target && eleNode.left != null) {                this.isTargetPath(eleNode.left, target, curSum, path, index);            }            // 右子节点            if (curSum < target && eleNode.right != null) {                this.isTargetPath(eleNode.right, target, curSum, path, index);            }        }    }
0 0