513.找树左下角的值
LeetCode - The World's Leading Online Programming Learning Platform
思路:本题要找出二叉树最下面一层最左边的值, 一眼看过去就是用层序遍历。 每一层的循环从左往右,开头的元素记录下来, 最后输出最后一层开头元素。
难点: 无
class Solution:
def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
q = deque([root])
ans = None
while q:
l = len(q)
for i in range(l):
cur_node = q.popleft()
if i == 0:
ans = cur_node.val
if cur_node.left: q.append(cur_node.left)
if cur_node.right: q.append(cur_node.right)
return ans
112. 路径总和
LeetCode - The World's Leading Online Programming Learning Platform
思路: 本题涉及到回溯算法,在从 root 到 leaf 访问每个节点的时候要记录走过路径的值。 采用迭代法时, 就是从root 开始, 向左右两个subtree 找是否有 路径到leaf,路径和为 targetSum - root.val (除去root值,新的targetSum)的值。 一直找下去, 如果到 leaf 的值等于 到它的时候的新targetSum, 输出True, 否则输出False。 如果左右两个有任何一个是 True, 那结果输出True。
难点:理解迭代的终止条件和输出。
class Solution:
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
if not root:
return False
if (not (root.left or root.right)) and root.val == targetSum: # leaf
return True
new_target = targetSum - root.val
ans = (self.hasPathSum(root.left, new_target) or self.hasPathSum(root.right, new_target))
return ans
113. 路径总和II
LeetCode - The World's Leading Online Programming Learning Platform
思路: 和上一题类似, 但是要求输出的所有root-leaf sum = target sum 的路径, 所以回溯起来会比上一题难。 如果迭代的话,可以考虑增加一个走过路径的 input, 如果碰到leaf, sum(path) + leaf.val == target sum 就吧 path.append(leaf.val 放入output list 中). 不过这里我试用了递归法。 stack 中放入 tuple ( cur_node, path, sum) 这种结构。
难点: 需要理清楚需要track 的是啥。
class Solution:
def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
ans = []
if not root:
return ans
st = deque()
st.append((root, 0, []))
while st:
cur_node, cur_sum, path = st.pop()
cur_sum += cur_node.val
path.append(cur_node.val)
if (not (cur_node.left or cur_node.right)) and cur_sum == targetSum: # leaf and get tarSum
ans.append(path)
if cur_node.right:
st.append((cur_node.right, cur_sum, path.copy()))
if cur_node.left:
st.append((cur_node.left, cur_sum, path.copy()))
return ans
106. 从中序与后序遍历序列构造二叉树
LeetCode - The World's Leading Online Programming Learning Platform
思路:首先如果只有一个值的时候, 直接输出一个 treenode 就可以了。 然后后序遍历中root的值是位于最后一位的。 然后在中序列表中找到相应位置i, 那么 0 - i-1 的值是root 右边的, i+1 之后的值是root 右边的。 同样把后序列表也一拆二。 然后分别长左右两边的subtree。
难点: 弄得中序和后序遍历元素的顺序
class Solution:
def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:
if len(inorder) == 1:
return TreeNode(inorder[0])
node = TreeNode(postorder[-1])
pos = inorder.index(node.val)
if pos!=0:
left_inorder = inorder[:pos]
left_postorder = postorder[:pos]
node.left = self.buildTree(left_inorder, left_postorder)
if pos!=len(inorder) - 1:
right_inorder = inorder[pos+1:]
right_postorder = postorder[pos:-1]
node.right = self.buildTree(right_inorder, right_postorder)
return node
105. 从前序与中序遍历序列构造二叉树
LeetCode - The World's Leading Online Programming Learning Platform
思路: 和上题一摸一样
class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
if len(inorder) == 1:
return TreeNode(inorder[0])
node = TreeNode(preorder[0])
pos = inorder.index(node.val)
if pos!=0:
left_inorder = inorder[:pos]
left_preorder = preorder[1:pos+1]
node.left = self.buildTree(left_preorder, left_inorder)
if pos!=len(inorder) - 1:
right_inorder = inorder[pos+1:]
right_preorder = preorder[pos+1:]
node.right = self.buildTree(right_preorder, right_inorder)
return node