代码随想录算法训练营第十六天 | 二叉树part04
513 找树左下角的值
思路:可以用层序遍历,一层一层的加入进去,然后输出最后一层的第一个数,就是最底层 最左边 节点的值。
def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
if not root:
return
deque = collections.deque([root])
stack = []
depth = 0
while deque:
level = []
size = len(deque)
for i in range(size):
node = deque.popleft()
level.append(node.val)
if node.left:
deque.append(node.left)
if node.right:
deque.append(node.right)
depth += 1
stack.append(level)
return stack[depth-1][0]
迭代法:
定义一个函数,这个函数需要接收的参数是node和depth,如果depth比当前的深度大的话,就更新最大深度。
然后取到node对应的val。
然后再对其左右节点进行递归。
为什么只取一个值呢,因为我们只需要知道最底层 最左边 节点的值。
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:
self.traversal(node.left, depth+1)
if node.right:
self.traversal(node.right, depth+1)
112 路径总和
思路:之前做过257 二叉树的所有路径,和这道题几乎一样,我们只需要把所有路径都列出来,然后找到最大值就行了,但是很明显时间复杂度很高。所以我们简化一下,设置一个最大值,然后往左往右进行遍历。比如说遍历到左孩子,那就把左孩子的值加进来,然后如果遍历到右孩子,就把刚刚左孩子的值减掉,再加入右孩子的值。
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
stack = []
if not root:
return False
result = []
self.a(root,stack,result)
if targetSum in result:
return True
else:
return False
def a(self,node,stack,result):
stack.append(node.val)
if not node.left and not node.right:
result.append(sum(stack))
if node.left:
self.a(node.left,stack,result)
node1 = stack.pop()
if node.right:
self.a(node.right,stack,result)
node1 =stack.pop()
113 路径求和II
思路:和上一题一模一样,但是得保存下来对应的数字。
def pathSum(self, root: Optional[TreeNode], targetSum: int):
stack = []
if not root:
return []
result = []
result2 = []
self.targetSum = targetSum
self.a(root,stack,result,result2)
return result2
def a(self,node,stack,result,result2):
stack.append(node.val)
if not node.left and not node.right:
result.append(sum(stack))
if sum(stack) == self.targetSum:
list_ = []
for i in stack:
list_.append(i)
result2.append(list_)
if node.left:
self.a(node.left,stack,result,result2)
node1 = stack.pop()
if node.right:
self.a(node.right,stack,result,result2)
node1 =stack.pop()
105 从前序与中序遍历序列构造二叉树
思路同下,只需要画出来下图就能做出来题目了。
def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
if not preorder:
return None
root_val = preorder[0]
root = TreeNode(root_val)
seperator_idx = inorder.index(root_val)
inorder_left = inorder[ : seperator_idx]
inorder_right = inorder[seperator_idx + 1 :]
preorder_left = preorder[ 1 : seperator_idx + 1]
preorder_right = preorder[seperator_idx + 1 : ]
root.left = self.buildTree(preorder_left , inorder_left)
root.right = self.buildTree(preorder_right , inorder_right)
return root
106 从中序与后序遍历序列构造二叉树
-
第一步:如果数组大小为零的话,说明是空节点了。
if not postorder : return None -
第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。
root_val = postorder[-1] root = TreeNode(root_val) -
第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点
seperator_idx = inorder.index(root_val) -
第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)
inorder_left = inorder[:seperator_idx] inorder_right = inorder[seperator_idx + 1:] -
第五步:切割后序数组,切成后序左数组和后序右数组
postorder_left = postorder[:seperator_idx] postorder_right = postorder[seperator_idx:len(postprder) - 1] -
第六步:递归处理左区间和右区间
root.left = self.buildTree(inorder_left,postorder_left) root.right = self.buildTree(inorder_right,postorder_right) return root
完整代码:
def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:
if not postorder:
return None
root_val = postorder[-1]
root = TreeNode(root_val)
seperator_idx = inorder.index(root_val)
inorder_left = inorder[:seperator_idx]
inorder_right = inorder[seperator_idx + 1:]
postorder_left = postorder[:seperator_idx]
postorder_right = postorder[seperator_idx:len(postorder) - 1]
root.left = self.buildTree(inorder_left,postorder_left)
root.right = self.buildTree(inorder_right,postorder_right)
return root