劍指offer | 面試題34:二叉樹中和爲某一值的路徑

轉載本文章請標明作者和出處
本文出自《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()


喜歡的朋友可以加我的個人微信,我們一起進步
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章