對於二叉樹的路徑綜合問題,隨著約束逐漸放寬,解題的難度也逐漸增強。
從根節點到葉節點
從任意節點到葉節點
從任意節點到任意節點
不需要遵循從上到下的順序(前面的都是需要的)
leetcode上面有四道題,從易到難,分別為:
路徑總和
路徑總和ii
路徑總和iii
路徑總和iv (此題需要會員,因此直接看不到)
還有一道和他們也是一脈相承的:
二叉樹中的最大路徑和
解題思路
只需要簡單的遞迴就可以了
class
solution
if(root.left ==null && root.right == null && root.val == targetsum)
return
haspathsum
(root.left,targetsum-root.val)
||haspathsum
(root.right,targetsum-root.val);}
}
需要加上乙個返回鍊錶,在每次到達葉子節點的時候判斷能否得到目標值
class
solution
private
void
helper
(treenode root,
int targetsum,list
list)
if(root.left == null && root.right ==null && root.val==targetsum)
list.
add(root.val)
;helper
(root.left,targetsum-root.val,list)
;helper
(root.right,targetsum-root.val,list)
; list.
remove
(list.
size()
-1);
}}
此題有兩種方法,分別是雙重遞迴和字首和方法雙重遞迴時間複雜度在二叉樹沒退化時是nologn,二叉樹退化為鍊錶後就是n^2
字首和方法時間複雜度是on,但是也需要額外的空間複雜度on來維護字首和
字首和方法算是乙個通用的方法,標記一下,以後重點關注
class
solution
dfs(root,sum)
;pathsum
(root.left,sum)
;pathsum
(root.right,sum)
;return res;
}private
void
dfs(treenode root,
int sum)
if(root.val == sum)
dfs(root.left,sum-root.val)
;dfs
(root.right,sum-root.val);}
}
class
solution
private
intcalculate
(treenode curr,
int currprefixsum,
int target)
int num =0;
currprefixsum += curr.val;
num += prefixsum.
getordefault
(currprefixsum - target,0)
; prefixsum.
put(currprefixsum,prefixsum.
getordefault
(currprefixsum,0)
+1);
num +=
calculate
(curr.left,currprefixsum,target)
+calculate
(curr.right,currprefixsum,target)
; prefixsum.
put(currprefixsum,prefixsum.
get(currprefixsum)-1
);return num;
}}
對於一棵深度小於 5 的樹,可以用一組三位十進位制整數來表示。
對於每個整數:
百位上的數字表示這個節點的深度 d,1 <= d <= 4。
十位上的數字表示這個節點在當前層所在的位置 p, 1 <= p <= 8。位置編號與一棵滿二叉樹的位置編號相同。
個位上的數字表示這個節點的權值 v,0 <= v <= 9。
給定乙個包含三位整數的公升序陣列,表示一棵深度小於 5 的二叉樹,請你返回從根到所有葉子結點的路徑之和。
樣例 1:
輸入: [113, 215, 221]
輸出: 12
解釋:這棵樹形狀如下:
路徑和 = (3 + 5) + (3 + 1) = 12.
用乙個map來維護節點位置和值的對映,這裡不可以直接用給定的陣列的下標來對映,因為可能有的節點為空,給定的樹並不是乙個完全二叉樹。
class
solution
int res=0;
dfs(1,
0,res,dict)
;return res;
}void
dfs(
int index,
int cur,
int& res,unordered_map<
int,
int>
&dict)
dfs(
2*index,cur,res,dict)
;dfs(2
*index+
1,cur,res,dict);}
};
private
intpathsum
(int
nums)
mapmap =
newhashmap
<
>()
;for
(int num:nums)
return
dfs(1,
0,map);}
private
intdfs
(int curr,
int sum,map
map)
//此節點是葉子節點if(
!map.
containskey
(curr*2)
&&!map.
containskey
(curr*2+
1))int val = map.
get(curr)
; sum += val;
return
dfs(curr*
2,sum,map)
+dfs
(curr*2+
1,sum,map)
;}
解題思路:乍一看好像很難(好吧,他標註的是hard)。但實際上卻很簡單,只需要知道每個節點加上他左子樹的最大和以及他右子樹的最大和就可以了。
class
solution
private
intgetmax
(treenode root)
int left = math.
max(0,
getmax
(root.left));
int right = math.
max(0,
getmax
(root.right));
res = math.
max(res,root.val+left+right)
;return math.
max(left,right)
+ root.val;
}}
二叉樹路徑總和
給定乙個二叉樹和乙個目標和,判斷該樹中是否存在根節點到葉子節點的路徑,這條路徑上所有節點值相加等於目標和。說明 葉子節點是指沒有子節點的節點。示例 給定如下二叉樹,以及目標和 sum 22,5 4 8 11 13 4 7 2 1 返回 true,因為存在目標和為 22 的根節點到葉子節點的路徑 5 ...
二叉樹的路徑總和
給定乙個二叉樹和乙個目標和,判斷該樹中是否存在根節點到葉子節點的路徑,這條路徑上所有節點值相加等於目標和。說明 葉子節點是指沒有子節點的節點。示例 給定如下二叉樹,以及目標和 sum 22,5 4 8 11 13 4 7 2 1返回 true,因為存在目標和為 22 的根節點到葉子節點的路徑 5 4...
二叉樹的路徑總和
definition for a binary tree node.struct treenode 給定乙個二叉樹和乙個目標和,找到所有從根節點到葉子節點路徑總和 等於給定目標和的路徑。說明 葉子節點是指沒有子節點的節點。示例 給定如下二叉樹,以及目標和 sum 22,5 4 8 11 13 4 7...