題目描述
輸入一顆二叉樹的根節點和一個整數,打印出二叉樹中結點值的和爲輸入整數的所有路徑。路徑定義爲從樹的根結點開始往下一直到葉結點所經過的結點形成一條路徑。
解題策略
先序dfs+回溯法 + 遞歸
解題思路參考Krahets
算法流程
FindPath(TreeNode root,int target)函數
- 參數:待判斷的樹,給定的和;
- 返回值: 返回所有路徑
help(TreeNode root, int tar)
-
遞歸參數: 當前節點 root ,當前目標值 tar。
-
遞歸終止條件:若節點 root 爲空,則直接返回。
-
遞歸部分:
- 路徑更新: 將當前節點值 root.val 加入路徑 path ;
- 目標值更新: tar = tar - root.val(即目標值 tar 從 sum 減至 00 );
- 路徑記錄: 當 ① root 爲葉節點 且 ② 路徑和等於目標值 ,則將此路徑 path 加入 res。
- 先序遍歷: 遞歸左 / 右子節點。
- 路徑恢復: 向上回溯前,需要將當前節點從路徑 path 中刪除,即執行 path.pop()。
-
返回值:無。
複雜度分析:
時間複雜度 O(N) : N 爲二叉樹的節點數,先序遍歷需要遍歷所有節點。
空間複雜度 O(N) : 最差情況下,即樹退化爲鏈表時,path 存儲所有樹節點,使用O(N) 額外空間。
注意
-
記錄路徑時若直接執行 res.add(path) ,則是將 path 對象加入了 res ;後續 path 改變時, res 中的 path 對象也會隨之改變。
正確做法:res.add(new ArrayList(path)),相當於複製了一個 path 並加入到 res 。 -
函數不要混淆了:求ArrayList的長度,是size(), 不是length()!!!
import java.util.ArrayList;
public class Solution {
ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> path = new ArrayList<Integer>();
public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
help(root, target);
return res;
}
void help(TreeNode root, int tar){
if(root == null) return;
path.add(root.val);
tar -= root.val;
if(tar == 0 && root.left == null && root.right == null){
res.add(new ArrayList(path));
}
help(root.left, tar);
help(root.right, tar);
path.remove(path.size()-1);// ArrayList的長度,是size(), 不是length()!!!!
}
}