轉載本文章請標明作者和出處
本文出自《Darwin的程序空間》
本文題目和部分解題思路來源自《劍指offer》第二版
題目
輸入一棵二叉樹和一個整數,打印出二叉樹中節點值的和爲輸入整數的所有路徑。從樹的根節點開始往下一直到葉節點所經過的節點形成一條路徑。
- 示例:
給定如下二叉樹,以及目標和 sum = 22,
-
返回
[ [5,4,11,2], [5,8,4,5] ]
解題分析
這道題,是要所有的結果的List集合,所以我們需要定義一個接受所有結果的全局變量res,如果有滿足的結果,就把結果裝到這個集合裏面;
然後我們發現題目是要一條從根節點一直到葉子節點的路徑,這條路徑的和要是所給的值,我們的想法就是拿着根節點root,和所求的路徑和sum往下遞歸,每遞歸到一層的節點,就用sum減去當前層節點的值,一直到sum==0並且是最後一層的節點,那麼這條路徑就是我們要找的結果路徑之一;
那麼,每次的路徑節點我都用什麼容器裝載呢?不能到最後我們得出sum==0卻發現之前遞歸的路徑我們都不知道,那不是竹籃打水一場空麼?所以我們可以定義一個List temp來裝載所有的路徑,沒錯,我們就用一個List來記錄所有的,但是有一個問題我們要清楚,List只在堆內存裏面的,無論你怎麼遞歸,List裏面的值都是不會變的,也就是說,對於所有的遞歸方法來說,List始終都是那一個List,所以我們要注意兩件事情:
1.找到結果之後不能直接把temp放到res裏面,因爲這樣的結果放到了res裏面,temp在之後遞歸的過程中值會變,這樣res裏面保存的講不再是希望的記過,我們找到一個答案之後,需要把它再重生成一個List之後再放入結果集裏面,這裏可以借用集合的構造函數來重構,new ArrayList<>(temp)。
2.我們需要在每次向左向右遞歸之後刪除上次遞歸的結果,也就是把temp裏面最後的一條數據刪掉,否則temp會帶着遞歸回來的數據,你會發現最後temp已經超過了樹的高度;
至於num,這個變量由於是存在在棧中的每次遞歸的方法中,每個方法的num都是獨立的變量,所以我們不用考慮“悔棋”的操作;
這道題要求我們對對象和局部變量在內存中的位置有比較好的瞭解,如果這方面有欠缺的小夥伴哪塊不會的話,可以來問我,或者查一下對應的資料;
代碼
ps:這裏筆者使用的jdk爲1.8、Python3.7版本
- java實現
*/
class Solution {
List<List<Integer>> res = new ArrayList<>();
public List<List<Integer>> pathSum(TreeNode root, int sum) {
if (Objects.isNull(root)) {
return res;
}
pathSum2(root, sum, new ArrayList<>());
return res;
}
public void pathSum2(TreeNode root, int sum, List<Integer> temp) {
sum -= root.val;
temp.add(root.val);
if (sum == 0 && Objects.isNull(root.left) && Objects.isNull(root.right)) {
res.add(new ArrayList<>(temp));
} else {
if (Objects.nonNull(root.left)) {
pathSum2(root.left, sum, temp);
temp.remove(temp.size() - 1);
}
if (Objects.nonNull(root.right)) {
pathSum2(root.right, sum, temp);
temp.remove(temp.size() - 1);
}
}
}
}
- Python實現
class Solution:
def __init__(self):
self.list_res = []
def pathSum(self, root: TreeNode, sum: int) -> List[List[int]]:
if root is None:
return []
self.pathSum2(root, sum, [])
return self.list_res
def pathSum2(self, root, sum_temp, list_temp):
sum_temp -= root.val
list_temp.append(root.val)
if sum_temp == 0 and root.left is None and root.right is None:
self.list_res.append(list_temp[:])
else:
if root.left is not None:
self.pathSum2(root.left, sum_temp, list_temp)
list_temp.pop()
if root.right is not None:
self.pathSum2(root.right, sum_temp, list_temp)
list_temp.pop()