思考
- 判断路径肯定使用深度遍历;
- 遍历到一个叶结点后需要返回上一父节点;因此在函数的最后应该将末尾元素删除;
- 保存结果方式,不可能在函数中定义容器,因此可以将结果作为函数参数,在函数递归过程中依次更新数据。(类似mergeSort中将整理的数组传递给新建的空间数组,最后再遍历更新原来的数组)
代码
public static ArrayList<ArrayList<Integer>> FindPath(BinaryTree root, int target) {
ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> tmp = new ArrayList<Integer>();
if(root == null) return res;
DFS(root, target, 0, res, tmp);
return res;
}
public static void DFS(BinaryTree root, int target, int curSum, ArrayList<ArrayList<Integer>> res, ArrayList<Integer> tmp){
if(root != null){
curSum += root.val;
tmp.add(root.val);
boolean isLeaf = (root.left == null) && (root.right == null);
if(curSum == target){
if(isLeaf){
ArrayList<Integer> t2 = new ArrayList<Integer>();
for(int i = 0; i < tmp.size(); i++){
t2.add(tmp.get(i));
}
res.add(t2);
}
}else if(curSum < target){
DFS(root.left, target, curSum, res, tmp);
DFS(root.right, target, curSum, res, tmp);
}
tmp.remove(tmp.size()-1);
}
}
总结
- 保存每条路径的tmp在整个函数过程中不断更新,因此不可能将其保存到最终结果中,需要每次找到合适的路径后新建一个ArrayList复制数据;
- 注意,每次递归遍历当前节点结束后,会自动回到它的父节点,因此保存路径的tmp删除当前节点的值。