力扣112 路徑總和(遞迴 迭代)

2021-10-05 06:05:36 字數 1623 閱讀 4888

力扣112. 路徑總和(遞迴、迭代)

給定乙個二叉樹和乙個目標和,判斷該樹中是否存在根節點到葉子節點的路徑,這條路徑上所有節點值相加等於目標和。

說明: 葉子節點是指沒有子節點的節點。

示例: 

給定如下二叉樹,以及目標和 sum = 22,

5/ \

4   8

/   / \

11  13  4

/  \      \

7    2      1

返回 true, 因為存在目標和為 22 的根節點到葉子節點的路徑 5->4->11->2。

複雜度分析

時間複雜度:我們訪問每個節點一次,時間複雜度為 o(n) ,其中 n 是節點個數。

空間複雜度:最壞情況下,整棵樹是非平衡的,例如每個節點都只有乙個孩子,遞迴會呼叫 n 次(樹的高度),因此棧的空間開銷是 o(n) 。但在最好情況下,樹是完全平衡的,高度只有 log(n),因此在這種情況下空間複雜度只有 o(log(n)) 。

最直接的方法就是利用遞迴,遍歷整棵樹:如果當前節點不是葉子,對它的所有孩子節點,遞迴呼叫 haspathsum 函式,其中 sum 值減去當前節點的權值;如果當前節點是葉子,檢查 sum 值是否為 0,也就是是否找到了給定的目標和。

#include "stdafx.h"

#include#include#include using namespace std;

struct treenode

};class solution

else

}return haspathsum(root->left, sum - root->val) || haspathsum(root->right, sum - root->val);

}};int main()

; p[0].left = &p[1]; p[0].right = &p[2];

p[1].left = &p[3]; p[1].right = &p[4];

p[2].left = &p[5]; p[2].right = &p[6];

p[3].left = &p[7]; p[3].right = &p[8];

p[4].left = &p[9];

p[5].right = &p[10];

solution s;

auto result = s.haspathsum(p, 15);

return 0;

}

其實,做為樹的遞迴題目是非常有套路可循的,因為樹有兩個分支,所以在遞迴裡也有兩個分支,一般是通過 遞迴 a(||,&&)遞迴 b 來實現分支的。只要明白了這一點,遞迴函式就不會很難設計。

所以我們從包含根節點的棧開始模擬,剩餘目標和為sum - root.val

然後開始迭代:彈出當前元素,如果當前剩餘目標和為 0 並且在葉子節點上返回 true;如果剩餘和不為零並且還處在非葉子節點上,將當前節點的所有孩子以及對應的剩餘和壓入棧中。

複雜度分析

時間複雜度:和遞迴方法相同是 o(n)。

空間複雜度:當樹不平衡的最壞情況下是 o(n) 。在最好情況(樹是平衡的)下是 o(logn)。

112 路徑總和

給定乙個二叉樹和乙個目標和,判斷該樹中是否存在根節點到葉子節點的路徑,這條路徑上所有節點值相加等於目標和。說明 葉子節點是指沒有子節點的節點。示例 給定如下二叉樹,以及目標和sum 22,5 48 1113 4 721返回true,因為存在目標和為 22 的根節點到葉子節點的路徑5 4 11 2。d...

112路徑總和

給定乙個二叉樹和乙個目標和,判斷該樹中是否存在根節點到葉子節點的路徑,這條路徑上所有節點值相加等於目標和。說明 葉子節點是指沒有子節點的節點。進行分析,遞迴終止的條件是什麼?一次遞迴中要進行什麼操作?遞迴想要返回什麼資訊?終止條件 結點為空 遞迴中操作 sum減去當前結點值,當sum為0且當前為葉子...

112 路徑總和

給定乙個二叉樹和乙個目標和,判斷該樹中是否存在根節點到葉子節點的路徑,這條路徑上所有節點值相加等於目標和。說明 葉子節點是指沒有子節點的節點。示例 給定如下二叉樹,以及目標和 sum 22,5 4 8 11 13 4 7 2 1返回 true,因為存在目標和為 22 的根節點到葉子節點的路徑 5 4...