浅说二叉树路径和

来源:互联网 发布:php空间试用 编辑:程序博客网 时间:2024/06/04 19:54

当我们沿着二叉树遍历的时候可以记录经过的节点,并且把这些节点的和加起来,这个和就是路径和。遍历的路径可以从根节点开始,也可以更加宽泛,从任何一个节点开始,只要方向是从双亲节点向孩子节点就行。

与路径和最相关的问题就是找指定和的路径,如果从根节点开始,找一个二叉树中是否有路径的路径和与给定数字相同,应该怎么找呢,这个问题并不难,先看代码:

public boolean hasPathSum(TreeNode root, int sum) {        if(root == null) {            return false;        }        else if(root.val == sum && (root.left == null && root.right == null)) {            return true;        }        else {            return hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val);        }    }

这个问题稍微升级一下,不仅要问是不是这棵树是否包这条路径,而且要求把所有的路径找出来。那应该怎么找呢,思路其实还是与之前是类似的。但是处理的时候考虑的问题要稍微多一点。

public List<List<Integer>> pathSum(TreeNode root, int sum) {        List<List<Integer>> arr = new ArrayList<List<Integer>>(), larr, rarr;        if(root == null) {            return arr;        }        else if(root.val == sum && root.left == null && root.right == null) {            arr.add(new ArrayList<Integer>(Arrays.asList(root.val)));        }        if((larr = pathSum(root.left, sum - root.val)).size() != 0) {            for(List<Integer> item : larr){                item.add(0, root.val);            }            arr.addAll(larr);        }        if((rarr = pathSum(root.right, sum - root.val)).size() != 0) {            for(List<Integer> item : rarr) {                item.add(0, root.val);            }            arr.addAll(rarr);        }        return arr;    }

用一个二维list存储最后的结果,list的第一个维度是是路径的条数,第二维才是每一条路径对应的节点集合。

同样的问题还可以继续挖掘,比如,现在的路径和不需要从根节点到叶子节点了,只要在树中是从上往下的就行了,如果要求一棵树中所有的满足给定路径和的路径,那应该怎么办呢?

public class Solution {    public int pathSum(TreeNode root, int sum) {        if(root == null)            return 0;        return findPath(root, sum) + pathSum(root.left, sum) + pathSum(root.right, sum);    }    public int findPath(TreeNode root, int sum){        int res = 0;        if(root == null)            return res;        if(sum == root.val)            res++;        res += findPath(root.left, sum - root.val);        res += findPath(root.right, sum - root.val);        return res;    }}

个人感觉这个问题比前边的问题难,对于这段代码首先要注意的是,在设计代码的时候不同的逻辑一定不能混在一起,刚开始逻辑没有分离开来,混在一起之后出现了一个很隐蔽的bug,所以要在设计的初期就杜绝这种问题。再者就是即便同一个路径,如果末尾的几个几点不同,也是不同的路径,那最后的几个不同的节点的路径和一定是等于0的,要在设计的时候考虑到。

该问题来自LeetCode OJ
- path-sum
- path-sum-ii
- path-sum-iii

0 0
原创粉丝点击