但又来了一件麻烦事,先序遍历便是先左后右。检查完左子树后,会对path就行修改,再去查找右子树,如何将path恢复到之前未进行左子树检查的状态?
比较好的做法是将path设为全局的,然后dfs的过程便是先序遍历的过程,一旦遍历到叶子结点,便将path最后的节点移除掉,这样在递归一层一层进行的时候将值添加进path,在递归返回的过程中将path最末尾的元素一个一个移除。这样便依靠递归的特性完成了路径的恢复。
例如对于树 10,5,12,5,7,#,#,#,#,#,#,#,#(层序遍历),path变化过程为 10,5,5 》》 10,5 》》 10,5,7 》》10,5 》》10 》》10,12 》》10 》》 null
因为最终遍历到叶子结点时,若发现符合规定的路径,是把path加入到结果集中,因为java中添加的是引用,而path是不断变化的,所以我们要新new一个当前路径的副本出来,防止添加进去的path都是相同的(最终path的状态)。
当然,这道题也可以用加法的思想,看dfs过程中能否加出target
public class Solution {
ArrayList> res = new ArrayList<>();
public ArrayList> FindPath(TreeNode root,int target) {
if (root == null) {
return res;
}
ArrayList path = new ArrayList<>();
findPath(root, target, path);
return res;
}
public void findPath(TreeNode root, int target, ArrayList path) {
if (root == null || target < 0) {
return;
}
if (root.left == null && root.right == null) {
if (target == root.val) {
path.add(root.val);
res.add(path);
}
return;
}
path.add(root.val);
//进行路径拷贝
ArrayList pathCopy = (ArrayList)path.clone();
findPath(root.left, target - root.val, path);
findPath(root.right, target - root.val, pathCopy);
return;
}
}
ArrayList> res = new ArrayList<>();
ArrayList path = new ArrayList<>();
public ArrayList> FindPath(TreeNode root,int target) {
if (root == null) {
return res;
}
findPath(root, target);
return res;
}
public void findPath(TreeNode root, int target) {
//因为FindPath中和 下面程序中都进行了判null操作,root绝对不可能为 null
path.add(root.val);
//已经到达叶子节点,并且正好加出了target
if (root.val == target && root.left == null && root.right == null) {
//将该路径加入res结果集中
res.add(new ArrayList(path));
}
//如果左子树非空,递归左子树
if (root.left != null) {
findPath(root.left, target - root.val);
}
//如果右子树非空,递归右子树
if (root.right != null) {
findPath(root.right, target - root.val);
}
//无论当前路径是否加出了target,必须去掉最后一个,然后返回父节点,去查找另一条路径,最终的path肯定为null
path.remove(path.size() - 1);
return;
}
ArrayList> res = new ArrayList<>();
ArrayList path = new ArrayList<>();
public ArrayList> FindPath(TreeNode root,int target) {
if (root == null) {
return res;
}
findPath(root, target, 0);
return res;
}
public void findPath(TreeNode root, int target, int sum) {
//因为FindPath中和 下面程序中都进行了判null操作,root绝对不可能为 null
path.add(root.val);
sum += root.val;
//已经到达叶子节点,并且正好加出了target
if (sum == target && root.left == null && root.right == null) {
//将该路径加入res结果集中
res.add(new ArrayList(path));
}
//如果左子树非空,递归左子树
if (root.left != null) {
findPath(root.left, target , sum);
}
//如果右子树非空,递归右子树
if (root.right != null) {
findPath(root.right, target ,sum);
}
//无论当前路径是否加出了target,必须去掉最后一个,然后返回父节点,去查找另一条路径,最终的path肯定为null
path.remove(path.size() - 1);
return;
}