力扣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...