代码随想录算法训练营Day18
513. Find Bottom Left Tree Value
一开始的朴素思想是, Bottom Left Node一定是一个左子树衍生的叶子结点. 但实际会有cur节点没有左子树,而右子树就成为了这一层的leftmost.
终止条件只需要在depth 增加时, 更新叶子结点的取值即可.
前序递归 & 层序迭代
class Solution:
def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
# 前序递归
def traversal(cur: TreeNode, depth: int):
nonlocal maxDepth, ans
if not cur: return
if (not cur.left) and (not cur.right) and depth > maxDepth:
maxDepth = depth
ans = cur.val
traversal(cur.left, depth + 1)
traversal(cur.right, depth + 1)
return
maxDepth = - 1
ans = 0
traversal(root, 1)
return ans
# TC: O(N)
# SC: O(log(N))
class Solution:
def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
# 层序迭代
q = [root]
cur = root
maxDepth = -1
ans = 0
depth = 0
while q:
depth += 1
for _ in range(len(q)):
cur = q.pop(0)
if (not cur.left) and (not cur.right) and depth > maxDepth:
maxDepth = depth
ans = cur.val
if cur.left: q.append(cur.left)
if cur.right: q.append(cur.right)
return ans
# 层序迭代 不需要depth变量的方法
q = [root]
cur = root
ans = 0
while q:
for i in range(len(q)):
cur = q.pop(0)
if i == 0:
ans = cur.val
if cur.left: q.append(cur.left)
if cur.right: q.append(cur.right)
return ans
112. Path Sum
前序递归: 一遍过好耶
class Solution:
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
# 前序递归
def traversal(cur: TreeNode, ss:int):
if not cur: return
if not (cur.left or cur.right): res.append(ss + cur.val)
if cur.left: traversal(cur.left, ss + cur.val)
if cur.right: traversal(cur.right, ss + cur.val)
return
res = []
traversal(root, 0)
return True if targetSum in res else False
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)
# 层序迭代
if not root: return False
q = []
q.append((root, root.val))
while q:
cur, curSum = q.pop(0)
if (not cur.left) and (not cur.right) and (curSum == targetSum):
return True
if cur.left: q.append((cur.left, curSum + cur.left.val))
if cur.right: q.append((cur.right, curSum + cur.right.val))
return False
113. Path Sum II
前序递归:一遍过好耶
class Solution:
def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
def dfs(cur: TreeNode, path: List, targetSum: int):
if not cur: return
if (not cur.left) and (not cur.right) and targetSum == cur.val:
res.append(path + [cur.val])
if cur.left: dfs(cur.left, path+[cur.val], targetSum - cur.val)
if cur.right: dfs(cur.right, path+[cur.val], targetSum - cur.val)
return
if not root: return []
res = []
path = []
dfs(root, path, targetSum)
return res
class Solution:
def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
# 层序迭代
if not root: return []
q = [(root, root.val, [root.val])] # Node, sum, path
res = []
while q:
cur, curSum, path = q.pop(0)
if (not cur.left) and (not cur.right) and curSum == targetSum:
res.append(path)
if cur.left:
q.append((cur.left, curSum+cur.left.val, path + [cur.left.val]))
if cur.right:
q.append((cur.right, curSum+cur.right.val, path + [cur.right.val]))
return res
106. Construct Binary Tree from Inorder and Postorder Traversal
前序和后序的共同特点,左右子树区间连在一起,难以分开. 所以只有“中序+前序”或“中序+后序”才能恢复原二叉树.
class Solution:
def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:
if not postorder: return None # 终止条件
# Inorder.length >= 1
root = TreeNode(postorder[-1])
# find the delimiter
# ii = inorder.index(postorder[-1])
ii = 0
for ii in range(len(postorder)):
if inorder[ii] == postorder[-1]: break
inorderLeft = inorder[:ii]
inorderRight = inorder[ii+1:]
postorderLeft = postorder[:len(inorderLeft)]
postorderRight = postorder[len(inorderLeft):-1]
root.left = self.buildTree(inorderLeft, postorderLeft)
root.right = self.buildTree(inorderRight, postorderRight)
return root
105. Construct Binary Tree from Preorder and Inorder Traversal
class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
if not preorder: return None
root = TreeNode(preorder[0])
index = inorder.index(preorder[0])
inorderLeft = inorder[:index]
inorderRight = inorder[index+1:]
preorderLeft = preorder[1:1+len(inorderLeft)]
preorderRIght = preorder[1+len(inorderLeft):]
root.left = self.buildTree(preorderLeft, inorderLeft)
root.right = self.buildTree(preorderRIght, inorderRight)
return root