題目描述
輸入一顆二叉樹的跟節點和一個整數,打印出二叉樹中結點值的和為輸入整數的所有路徑。路徑定義為從樹的根結點開始往下一直到葉結點所經過的結點形成一條路徑。(注意: 在返回值的list中,數組長度大的數組靠前)
分析
由於路徑是從根節點出發到葉子節點的,因此我們需要首先遍歷根節點,只有前序遍歷是首先訪問根節點的。
當訪問某一個節點時,我們不知道前面經過了哪些節點,所以我們需要將經過的路徑上的節點保存下來,每訪問一個節點,我們需要把當前節點添加到路徑中去。
在遍歷下一個節點前,先要回到當前節點的父節點,在去其他節點,當回到父節點時,之前遍歷的那個節點已經不在當前路徑中了,所以需要刪除之前在路徑中的那個節點。
代碼
//節點類
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>> listAll = new ArrayList<ArrayList<Integer>>(); //保存所有符合條件的路徑
ArrayList<Integer> list = new ArrayList<Integer>(); //當前路徑
return SeekPath(listAll, list, root, target);
}
public ArrayList<ArrayList<Integer>> SeekPath(ArrayList<ArrayList<Integer>> listAll, ArrayList<Integer> list, TreeNode root,int target) {
if(root == null) return listAll;
list.add(root.val);
target -= root.val;
if(target == 0 && root.left == null && root.right == null) { //當前路徑和是指定值且當前節點是葉子節點
listAll.add(new ArrayList<Integer>(list));
}
SeekPath(listAll, list, root.left, target);
SeekPath(listAll, list, root.right, target);
list.remove(list.size() - 1); //遞歸回到父節點時需要在路徑中刪除上一個節點信息
return listAll;
}
public static void main(String[] args) {
TreeNode t1 = new TreeNode(10);
TreeNode t2 = new TreeNode(5);
TreeNode t3 = new TreeNode(12);
TreeNode t4 = new TreeNode(4);
TreeNode t5 = new TreeNode(7);
t1.left = t2;
t1.right = t3;
t2.left = t4;
t2.right = t5;
Solution s = new Solution();
System.out.println(s.FindPath(t1, 22));
}
}