題目:輸入一顆二叉樹的跟節點和一個整數,打印出二叉樹中結點值的和爲輸入整數的所有路徑。路徑定義爲從樹的根結點開始往下一直到葉結點所經過的結點形成一條路徑。
(注意: 在返回值的list中,數組長度大的數組靠前)
解析:
①從根節點開始遞歸訪問左子樹同時將給出的整數減去訪問的結點值,當葉子結點的值等於剩餘整數時,說明該路徑滿足條件,將其保存到List中;
②不管滿不滿足條件,都對訪問過的結點後退一步,訪問當前結點的下一葉子結點繼續尋找其他路徑;
③同樣的操作訪問根節點的右子樹;
public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
ArrayList<ArrayList<Integer>> List = new ArrayList<>();
ArrayList<Integer> path = new ArrayList<>();
AllPath(root,target,path,List);//將滿足所有路徑和爲target的存入
Collections.sort(List, new Comparator<ArrayList<Integer>>(){
@Override
public int compare(ArrayList<Integer> o1, ArrayList<Integer> o2) {
if (o1.size() < o2.size()){
return 1;//正數交換位置,負數不交換位置,o1<o2,交換位置--->o2 o1 降序
}
return -1;
}
});
return List;
}
public void AllPath(TreeNode root,int target,ArrayList<Integer> path,ArrayList<ArrayList<Integer>> List){
if (root == null) return;
path.add(root.val);//將從根節點開始到到葉子結點的路徑的值加入ArrayList中
if (target==root.val&&root.left==null&&root.right==null){
//path只是一個引用,ArrayList(Collection<? extends E> c)
List.add(new ArrayList<Integer>(path));//這纔是添加一個集合到List中
}else{
AllPath(root.left,target-root.val,path,List);//遞歸到root的左子樹
AllPath(root.right,target-root.val,path,List);//遞歸到root的右子樹
}
path.remove(path.size()-1);//如果沒有當前路徑沒有找到,需要後退一個節點繼續找(長度-1)
}