剑指offer-二叉树中和为某一值的路径
题目:二叉树中和为某一值的路径
题目描述:输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。
思路:这道题用递归求解是最简单的,好久没有对递归过程进行过分析了,感觉都忘完了。不过,好在我聪明又机智,进过短暂的回想后,我又再次悟出了递归的精华。结合下面代码,我用一个例子进行一下说明
1
/ \
2 3
/ \ / \
4 5 6 7
对于上面这个二叉树,假设target=8,开始时root=1(为方便说明,这里直接用节点代替节点的值)
1.进入递归函数,递归的截至条件是root==null||target<0,不满足(这个截止条件时针对于在递归中途不满足时便直接跳出本层递归,回到上一层),往下直接执行
此时list={1},target=8-1=7,target==0且到达了叶节点时表明找到了这条路径,此时不满足,往下执行
对root.left调用递归函数
2.此时,这一层的root=2,target=5,2下面还有左右节点,所以继续对root.left进行递归调用,此时list={1,2}
3.此时,这一层的root=4,target=1,此时list={1,2,4}
由于4下面没有左右节点,所以不会对4的左右节点进行递归调用,往下执行
到达左右节点都判断完的这一步时,说明此路已找完,需要回退(这里的返回针对的是这条路径的左右子树都找完了,所以需要返回到上一层去其他路看看),
list吐出最后一个节点,list={1,2}
4.递归函数返回到4的上面一层2,继续对2的右子树进行递归,这一层的target任为5
5.对2 的右子树递归调用后,root=5,target=0,list={1,2,5}
满足路径条件,在res中新建一个List,把list的值复制过去
6.5无左右子树,所以路径回退,回退到节点2,list吐出5
7.在root=2这一层,左右节点均判断完了,说明这个方向的路径已经找完了,路径继续回退,list吐出2,此时list={1}
8.在root=1这一层,此时target=7,左子树的路径都找完了,对root.right再进行递归调用
9.此时root=3,target=4,...
10.继续以上同样的递归,直到1的右子树路径全部找完,此时1的左右子树均已找完,list吐出1,此时list={}
函数返回最终的res
代码:
1 import java.util.ArrayList; 2 3 public class Solution { 4 ArrayList<ArrayList<Integer>>res=new ArrayList<>(); 5 ArrayList<Integer>list=new ArrayList<>(); 6 public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) { 7 if(root==null||target<0) return res; 8 list.add(root.val); 9 target-=root.val; 10 if(target==0&&root.left==null&&root.right==null){ 11 res.add(new ArrayList<Integer>(list)); 12 } 13 if(root.left!=null) FindPath(root.left,target); 14 if(root.right!=null)FindPath(root.right,target); 15 list.remove(list.size()-1); 16 return res; 17 } 18 }
还可以用先序遍历的思想求解
1 import java.util.ArrayList; 2 import java.util.Stack; 3 public class Solution { 4 public ArrayList<ArrayList<Integer>> FindPath(TreeNode root, 5 int target) { 6 ArrayList<ArrayList<Integer>> pathList= 7 new ArrayList<ArrayList<Integer>>(); 8 if(root==null) 9 return pathList; 10 Stack<Integer> stack=new Stack<Integer>(); 11 FindPath(root,target,stack,pathList ); 12 return pathList; 13 14 } 15 private void FindPath(TreeNode root, int target, 16 Stack<Integer> path, 17 ArrayList<ArrayList<Integer>> pathList) { 18 if(root==null) 19 return; 20 if(root.left==null&&root.right==null){ 21 if(root.val==target){ 22 ArrayList<Integer> list= 23 new ArrayList<Integer>(); 24 for(int i:path){ 25 list.add(new Integer(i)); 26 } 27 list.add(new Integer(root.val)); 28 pathList.add(list); 29 } 30 } 31 else{ 32 path.push(new Integer(root.val)); 33 FindPath(root.left, target-root.val, path, pathList); 34 FindPath(root.right, target-root.val, path, pathList); 35 path.pop(); 36 } 37 38 } 39 }