- ,这道题目主要让我深刻的了解到引用传递,若把传递进去的引用赋值,函数结束后,还是原来的内容,但是特别注意 :若是容器之类的,它的add操作、remove操作,这不是引用复赋值,而是改变其内容,所以当函数结束时,该引用指向的值则已经改变了。
- 然而,这道题还让我了解到更深层次,如下代码,是错误的,无论用例是什么,传出了的ArrayList<ArrayList<Integer>>都为空,是因为每次找到了路径之后,加进来一个路径ArrayList<Integer>,但是后面改变了这个ArrayList<Integer>,则ArrayList<ArrayList<Integer>>里的ArrayList<Integer>也会改变。
import java.util.ArrayList;
import java.util.Stack;
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
ArrayList<ArrayList<Integer>> pathList = new ArrayList<ArrayList<Integer>>();
if(root == null){ //如果此树为空则直接返回
return pathList;
}
Stack<TreeNode> path = new Stack<TreeNode>();//定义栈来存储一条路径
ArrayList<Integer> a=new ArrayList<Integer>();
int c=0;
FindPath(root, target,c, path,a, pathList); //调用查找方法
return pathList;
}
public void FindPath(TreeNode t,int target,int currentSum,Stack<TreeNode> s,ArrayList<Integer> at,ArrayList<ArrayList<Integer>> aat){
s.push(t);
currentSum+=t.val;
at.add(t.val);
if(t.left==null&&t.right==null&¤tSum==target){
aat.add(at);
currentSum-=t.val;
}
if(t.left!=null)
FindPath(t.left,target,currentSum,s,at,aat);
if(t.right!=null)
FindPath(t.right,target,currentSum,s,at,aat);
s.pop();
at.remove(at.size()-1);
}
}
正确的代码如下,就在每次找到某条符合的路径的时候,创建一个ArrayList<Integer>,将所有值带进去。
import java.util.ArrayList;
import java.util.Stack;
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
ArrayList<ArrayList<Integer>> pathList = new ArrayList<ArrayList<Integer>>();
if(root == null){ //如果此树为空则直接返回
return pathList;
}
Stack<TreeNode> path = new Stack<TreeNode>();//定义栈来存储一条路径
int c=0;
FindPath(root, target,c, path, pathList); //调用查找方法
return pathList;
}
public void FindPath(TreeNode t,int target,int currentSum,Stack<TreeNode> s,ArrayList<ArrayList<Integer>> aat){
s.push(t);
currentSum+=t.val;
if(t.left==null&&t.right==null&¤tSum==target){
//正确代码主要就是下面这一段区别,并且这个递归函数没有ArrayList<Integer>这个形参
ArrayList<Integer> a=new ArrayList<Integer>();
for(TreeNode tr:s)
a.add(tr.val);
aat.add(a);
}
if(t.left!=null)
FindPath(t.left,target,currentSum,s,aat);
if(t.right!=null)
FindPath(t.right,target,currentSum,s,aat);
s.pop();
currentSum-=t.val;
}
}
结果如下
还有一种将stack里面不放TreeNode,就放Integer,结果如下,空间复杂度和放TreeNode一样
原本还想用图的深度遍历来做,即不用递归的方式,但是DFS需要有一个boolean[] 来标记每个节点是否被访问过,但由于二叉树没有节点数这个信息,所以不好用这个方法来做,在这里先不做解答,下面代码是错的,暂时没想到好的方法解决,所以先放这吧
import java.util.ArrayList;
import java.util.Stack;
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
Stack<TreeNode> s=new Stack<TreeNode>();
int res=0;
ArrayList<ArrayList<Integer>> al=new ArrayList<ArrayList<Integer>>();
if(root==null)
return al;
s.push(root);
ArrayList<Integer> a=new ArrayList<Integer>();
while(!s.isEmpty()){
TreeNode p=s.peek();
res+=p.val;
a.add(p.val);
if(p.left==null&&p.right==null){
if(res==target){
al.add(a);
res-=p.val;
}
a.remove(p);
s.pop();
}
if(p.right!=null)
s.push(p.right);
if(p.left!=null)
s.push(p.left);
}
return al;
}
}