题解 | #二叉树中和为某一值的路径(三)#

二叉树中和为某一值的路径(三)

https://www.nowcoder.com/practice/965fef32cae14a17a8e86c76ffe3131f

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param root TreeNode类
     * @param sum int整型
     * @return int整型
     */
    // public int FindPath (TreeNode root, int sum) {
    //     // write code here


    //     ArrayList<ArrayList<Integer>> resultList = new ArrayList<ArrayList<Integer>>();
    //     ArrayList<ArrayList<Integer>> totalList = new ArrayList<ArrayList<Integer>>();

    //     ArrayList<Integer> levelList = new ArrayList<Integer>();

    //     if (root == null) {
    //         return 0;
    //     }

    //     FindAllPath(root, totalList, levelList);

    //     for (int i = 0; i < totalList.size(); i++) {
    //         ArrayList<Integer> level = totalList.get(i);
    //         FindTargetPath(level, resultList, sum);

    //         System.out.print("第" + i + "条路径的节点值:");
    //         for (int j = 0; j < level.size(); j++) {
    //             System.out.print(level.get(j) + ",");
    //             //那么,如何从这个数组中,找到连续值之和,为目标数呢?

    //         }
    //         System.out.println();
    //     }

    //     return resultList.size();
    // }

    private void FindTargetPath(ArrayList<Integer> list,
                                ArrayList<ArrayList<Integer>> resultList, int num) {
        int startIndex = 0;
        int endIndex = 0;

        firstLoop:
        for (int i = 0; i < list.size() - 1; i++) {
            //依次从头节点到尾节点,移动开始指针,往后计算,可以做到
            ArrayList<Integer> oneResult = new ArrayList<Integer>();

            int sum = list.get(i);
            oneResult.add(sum);
            for (int j = i + 1; j < list.size(); j++) {

                sum += list.get(j);
                oneResult.add(list.get(j));

                if (sum == num) {
                    //把结果保存下来,并跳出本循环
                    //这里有个难点,如何剔除重复呢?换句话说,需要剔除重复吗?
                    resultList.add(oneResult);
                    continue firstLoop;
                }
            }
        }
    }

    private void FindAllPath(TreeNode node,
                             ArrayList<ArrayList<Integer>> resultList, ArrayList<Integer> levelList) {

        //这题区别于上一题,不要求到叶子节点,而且可以从任一节点开始都行,只要达成和是目标值,就符合条件。

        //上一道题的好处,是每条路径都从根节点触发, 这里难就难在,出发点是不定的。

        //包括叶子节点在内的所有节点,都可以是出发点。

        //那么。该怎么去遍历取出符合的路径呢?

        //欸,可以先把所有的根到叶子路径,组成一个集合,然后从集合中取出某一个路径,从这个路径中取出连续的几个点,能够组成这个和,说明符合路径。

        //问题转化成了,求一个数组中,连续的几个值之和,为目标数的问题。

        //那么,我先找出从根到叶的所有路径,然后遍历这些路径,从每条路径中找出连续的点之和为目标数的情况



        if (node == null) {
            resultList.add(levelList);
            return;
        }

        ArrayList<Integer> levelListLeft = new ArrayList<Integer>();
        levelListLeft.addAll(levelList);
        ArrayList<Integer> levelListRight = new ArrayList<Integer>();
        levelListRight.addAll(levelList);

        levelListLeft.add(node.val);
        levelListRight.add(node.val);

        //这里要区别一下叶子节点和普通节点,叶子节点,左右子节点都为null,如果这样写,会+两遍集合进去,因此当叶子节点时,要剔除一次!

        if (node.left == null && node.right == null) {
            FindAllPath(node.left,  resultList, levelListLeft);
        } else {
            FindAllPath(node.left,  resultList, levelListLeft);
            FindAllPath(node.right, resultList, levelListRight);
        }

    }

    //优化一下,在寻找路径的时候,直接做计算,这样可以不用保存路径结果,直接开始路径计数,优化重复计算



    int res = 0;//统计路径数
    public int FindPath (TreeNode root, int sum) {
        if(root == null){
            return 0;
        }

        FindOnePath(root,sum);//寻找从根节点触发的,所有路径数

        FindPath(root.left,sum);//寻找从左节点出发的路径数。
        FindPath(root.right,sum);//寻找从右节点出发的路径数。        
        return res;
    }

    private void FindOnePath(TreeNode node, int num) {
        if (node == null){
            return;
        }

        if(num == node.val){
            res++;
        }

        FindOnePath(node.left, num - node.val);
        FindOnePath(node.right, num - node.val);
    }


}

全部评论

相关推荐

09-17 17:09
门头沟学院 Java
雨忄:有人给出过解法,拖晚点去,然后到时候再找其他理由商量,既增加他们的筛人成本,不一定会给你收回offer ,也能占位避免工贼
秋招的嫡长offer
点赞 评论 收藏
分享
09-12 11:55
已编辑
湖南工商大学 Java
那一天的Java_J...:这种一堆问题的,别去
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务