題目:輸入一顆二叉樹的根節點和一個整數,打印出二叉樹中結點值的和爲輸入整數的所有路徑。路徑定義爲從樹的根結點開始往下一直到葉結點所經過的結點形成一條路徑。(注意: 在返回值的list中,數組長度大的數組靠前)
解題思路:
採用一種“減法”思想,當檢查一棵樹從根到葉子節點形成的路徑的和是否爲target時,先將當前根節點的值 root.val 加入path, 然後檢查它的左子樹(若非空),看從左子樹的根到葉子節點形成的路徑的和是否爲 target - root.val (遞歸), 然後同樣的道理去遞歸檢查右子樹(若非空),這便是大致的思路。
- 但這道題麻煩的一點是,它要求記錄下所有符合標準的路徑,這便用到了dfs的特性。
-
但又來了一件麻煩事,先序遍歷便是先左後右。檢查完左子樹後,會對path就行修改,再去查找右子樹,如何將path恢復到之前未進行左子樹檢查的狀態?
-
比較好的做法是將path設爲全局的,然後dfs的過程便是先序遍歷的過程,一旦遍歷到葉子結點,便將path最後的節點移除掉,這樣在遞歸一層一層進行的時候將值添加進path,在遞歸返回的過程中將path最末尾的元素一個一個移除。這樣便依靠遞歸的特性完成了路徑的恢復。
package jianzhi_offer;
import java.util.ArrayList;
public class P34_Solution {
ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> path = new ArrayList<Integer>();
public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
if(root == null)
return res;
findPath(root,target);
return res;
}
public void findPath(TreeNode root, int target) {
path.add(root.val);
if(root.val == target && root.left == null && root.right == null)
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);
}
path.remove(path.size() - 1);
return;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}