程式碼隨想錄演算法訓練營第17天
找樹左下角的值
https://leetcode.cn/problems/find-bottom-left-tree-value/
找樹左下角的值程式碼隨想錄
https://leetcode.cn/problems/find-bottom-left-tree-value/
路徑總和
https://leetcode.cn/problems/path-sum/description/
路徑總和2
https://leetcode.cn/problems/path-sum-ii/description/
路徑總和程式碼隨想錄
https://programmercarl.com/0112.路徑總和.html#思路
106.從中序與後序遍歷序列構造二叉樹
https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal/description/
106.從中序與後序遍歷序列構造二叉樹
https://programmercarl.com/0106.從中序與後序遍歷序列構造二叉樹.html#思路
找樹左下角的值
題
給定一個二叉樹的 根節點 root,請找出該二叉樹的 最底層 最左邊 節點的值。
假設二叉樹中至少有一個節點。
題解重點
- 遞迴法:先遍歷curr.left 才是左下角;
- 迭代法:層序遍歷法非常輕鬆
class Solution:
def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
if not root:
return root
self.depth = float('-inf')
self.res = root.val
self.trans(root,0)
return self.res
def trans(self,curr,depth):
if not curr.right and not curr.left:
if depth>self.depth:
self.depth = depth
self.res = curr.val
return
if curr.left:
depth = depth+1
self.trans(curr.left,depth)
depth = depth-1
if curr.right:
depth = depth+1
self.trans(curr.right,depth)
depth = depth-1
層序遍歷迭代法
class Solution:
def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
if not root:
return None
res = []
queue = collections.deque([root])
while queue:
line = []
for i in range(len(queue)):
curr = queue.popleft()
line.append(curr.val)
if curr.left:
queue.append(curr.left)
if curr.right:
queue.append(curr.right)
res.append(line)
return res[-1][0]
路徑總和
題目1:路徑總和1
給你二叉樹的根節點 root 和一個表示目標和的整數 targetSum 。判斷該樹中是否存在 根節點到葉子節點 的路徑,這條路徑上所有節點值相加等於目標和 targetSum 。如果存在,返回 true ;否則,返回 false 。
葉子節點 是指沒有子節點的節點。
題解重點
- 遞迴法: 1.複雜法:準確傳遞 targetsum和value 不需要回溯;2.簡約法:呼叫原函式即可
- 迭代法:棧裡記憶體(node,val_sum)
題解程式碼
複雜遞迴法
class Solution:
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
if not root:
return False
if self.trans(root,targetSum,0):
return True
else:
return False
def trans(self,curr,targetSum,value):
value = value+curr.val
if not curr.right and not curr.left:
if value==targetSum:
return True
else:
return False
if curr.left:
if self.trans(curr.left,targetSum,value):
return True
# value = value - curr.left.val
if curr.right:
if self.trans(curr.right,targetSum,value):
return True
# value = value - curr.right.val
簡約遞迴法
class Solution:
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
if not root:
return False
if not root.left and not root.right and targetSum==root.val:
return True
return self.hasPathSum(root.left,targetSum-root.val) or self.hasPathSum(root.right,targetSum-root.val)
迭代法
class Solution:
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
if not root:
return False
st = [root]
res_st = [root.val]
while st:
curr = st.pop()
res_i = res_st.pop()
if curr:
if curr.right:
st.append(curr.right)
res_st.append(res_i+curr.right.val)
if curr.left:
st.append(curr.left)
res_st.append(res_i+curr.left.val)
st.append(curr)
st.append(None)
res_st.append(res_i)
res_st.append(None)
else:
node = st.pop()
res = res_st.pop()
if not node.left and not node.right:
if res==targetSum:
return True
return False
路徑總和2
題目
給你二叉樹的根節點 root 和一個整數目標和 targetSum ,找出所有 從根節點到葉子節點 路徑總和等於給定目標和的路徑。
葉子節點 是指沒有子節點的節點。
題解重點:同上題
題解程式碼:
class Solution:
def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
self.res = []
path = []
if not root:
return self.res
self.trans(root,path,targetSum)
return self.res
def trans(self,curr,path,targetSum):
path.append(curr.val)
if not curr.left and not curr.right:
if sum(path)==targetSum:
self.res.append(path[:])
return
if curr.left:
self.trans(curr.left,path,targetSum)
path.pop()
if curr.right:
self.trans(curr.right,path,targetSum)
path.pop()
class Solution:
def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
if not root:
return []
res = [] ##最終結果存放
st = [(root,[root.val])] ##遍歷點
while st:
curr,path_i = st.pop()
if curr:
if curr.right:
st.append((curr.right,path_i+[curr.right.val]))
if curr.left:
st.append((curr.left,path_i+[curr.left.val]))
st.append((curr,path_i))
st.append((None,None))
else:
node,path_i = st.pop()
if not node.right and not node.left:
if sum(path_i)==targetSum:
res.append(path_i)
return res
106.從中序與後序遍歷序列構造二叉樹
題目
給定兩個整數陣列 inorder 和 postorder ,其中 inorder 是二叉樹的中序遍歷, postorder 是同一棵樹的後序遍歷,請你構造並返回這顆 二叉樹 。
題解重點
- 流程步驟:
1.判斷後序數列是否為空;為空說明沒有根節點,返回根節點;
2.如果不為空,最後一個節點為根節點;
3.找到根節點在中序序列的位置;
4.切割中序列;
5.切割後序列;
6.遞迴處理左子樹和右子樹;
題解程式碼
class Solution:
def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:
if not postorder:
return None
root = TreeNode(postorder[-1])
cut_point_1 = inorder.index(root.val)
# print(f"cut_point{cut_point_1}")
in_left,in_right = inorder[:cut_point_1],inorder[cut_point_1+1:]
# print(f"in_left:{in_left},in_right:{in_right}")
pos_left,pos_right = postorder[:len(in_left)],postorder[len(in_left):-1]
# print(f"pos_left:{pos_left},pos_right:{pos_right}")
root.left = self.buildTree(in_left,pos_left)
root.right = self.buildTree(in_right,pos_right)
return root