513. 找树左下角的值
- 这题最先想的就是层次遍历法很简单,只需要输出最后一行的第一个就行
- 硬用递归的话,就想到,如果按照一个顺序递归的话,似乎可以做到先左后右,这样的话只在深度增长的时候覆盖一次result,就不会在右边节点的时候进行覆盖操作。
- 但其实递归的前序后序还是有点懵,因此一开始写出来的是找树右下角的值。
- 但实际上depth_left>=depth_right这句,加上等于就是找左边,不加=就是找右边?
class Solution:
def traversal(self, root):
if root is None:
return 0, root
if not root.left and not root.right:
return 1, root.val
depth_left, left_node_left = self.traversal(root.left)
depth_right, left_ndoe_right = self.traversal(root.right)
if depth_left >= depth_right:
return depth_left + 1, left_node_left
else: return depth_right + 1, left_ndoe_right
def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
# 递归,返回结果?
# 返回深度?如果按先左后右的覆盖顺序,是不是第一个出现的就是最左
depth, left_node = self.traversal(root)
return left_node
# 层次遍历
q = collections.deque()
q.append(root)
while(q):
res = []
for i in range(len(q)):
node = q.popleft()
res.append(node.val)
if node.left:
q.append(node.left)
if node.right:
q.append(node.right)
return res[0]
题解里的递归:
- 又加上了回溯?回溯是因为有一个参数需要传入递归的函数,但是本身这个函数在运行的时候不希望这个参数是变化的?但是这里的情况,如果不递归有影响吗?
- 这里是depth > self.max_depth的时候,对result进行覆盖。而不是我之前写的left>=right。因此这里就存在前序的问题,前序和后序的结果应该是不一样的。
class Solution:
def findBottomLeftValue(self, root: TreeNode) -> int:
self.max_depth = float('-inf')
self.result = None
self.traversal(root, 0)
return self.result
def traversal(self, node, depth):
if not node.left and not node.right:
if depth > self.max_depth:
self.max_depth = depth
self.result = node.val
return
if node.left:
depth += 1
self.traversal(node.left, depth)
depth -= 1
if node.right:
depth += 1
self.traversal(node.right, depth)
depth -= 1
112. 路径总和
- 自己写的递推,这次输出是结果,参数是target和sum。当叶子节点的时候输出sum的结果。
class Solution:
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
return self.traversal(root, targetSum, 0)
def traversal(self, root, target, sum_):
if not root:
return False
sum_ += root.val # 这里加上了,后面是不是要回溯啊
if not root.left and not root.right: # 叶子节点就进行处理
if sum_ == target:
return True
else:
return False
left = self.traversal(root.left, target, sum_)
right = self.traversal(root.right, target, sum_)
sum_ -= root.val # 回溯?
return left or right
- 看了题解之后,感觉可以只改target,不用传sum这个参数。这样的话递归的时候传入target-root.val,相当于隐形递归
class Solution:
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
return self.traversal(root, targetSum)
def traversal(self, root, target):
if not root:
return False
# sum_ += root.val # 这里加上了,后面是不是要回溯啊
if not root.left and not root.right: # 叶子节点就进行处理
if root.val == target:
return True
else:
return False
left = self.traversal(root.left, target-root.val)
right = self.traversal(root.right, target-root.val)
# sum_ -= root.val # 回溯?
return left or right
113. 路径总和ii
- 但我试了一下,在if里回溯,和在if外回溯,好像都一样。但是当left和right都有的时候,不就相当于是一个回溯一步和两步吗,是不一样的吧。所以回溯到底是啥???搞不懂。
class Solution:
def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
path_res = []
self.path_sum(root, targetSum, [], path_res)
return path_res
def path_sum(self, root, target, path, path_res):
if not root:
return
path.append(root.val)
if not root.left and not root.right and root.val == target:
print(path)
path_res.append(list(path))
if root.left:
self.path_sum(root.left, target-root.val, path, path_res)
path.pop()
if root.right:
self.path_sum(root.right, target-root.val, path, path_res)
path.pop()
106. 从中序与后序遍历序列构造二叉树
- 蛮好想的递归,一次就ac了。所以下一题没写。
class Solution:
def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:
# 感觉可以递归
n = len(postorder)
if n == 0:
return
if n == 1:
return TreeNode(inorder[0])
mid = postorder[n-1]
# 找切割点.
i = inorder.index(mid)
mid_node = TreeNode(mid)
left = self.buildTree(inorder[0:i], postorder[0:i])
right = self.buildTree(inorder[i+1:], postorder[i:n-1])
mid_node.left = left
mid_node.right = right
return mid_node