当前位置:   article > 正文

代码随想录学习Day 16

代码随想录学习Day 16

513.找树左下角的值

题目链接

讲解链接

注意树左下角的值指的是二叉树最底层最左边节点的值。所以使用层次遍历的方法比较简单,遍历每一层时都将该层的最左边节点的值保存下来,当遍历结束后将这个值返回即可。

  1. class Solution:
  2. def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
  3. if not root:
  4. return None
  5. queue = deque([root])
  6. while queue:
  7. for i in range(len(queue)):
  8. node = queue.popleft()
  9. if i == 0:
  10. result = node.val # 记录当前层最左边节点的值
  11. if node.left:
  12. queue.append(node.left)
  13. if node.right:
  14. queue.append(node.right)
  15. return result

112.路径总和

题目链接

讲解链接

递归法:

1.递归函数参数及返回值:当前遍历节点以及一个计数器,返回值为bool型变量。

def traversal(self, cur, count):

2.递归终止条件:采用递减的方式,让计数器count初始为目标和,然后每次减去遍历路径节点上的数值。如果最后count == 0,同时到了叶子节点的话,说明找到了目标和。如果遍历到了叶子节点,count不为0,就是没找到。

  1. if not cur.left and not cur.right:
  2. return True if result == 0 else False

3.单层递归逻辑:因为终止条件是判断叶子节点,所以递归的过程中不让空节点进入递归。递归函数是有返回值的,如果递归函数返回true,说明找到了合适的路径,应该立刻返回。

  1. if cur.left:
  2. result -= cur.left.val
  3. if self.traversal(cur.left, result):
  4. return True
  5. result += cur.left.val
  6. if cur.right:
  7. result -= cur.right.val
  8. if self.traversal(cur.right, result):
  9. return True
  10. result += cur.right.val
  11. return False

 递归法完整代码:

  1. class Solution:
  2. def traversal(self, cur, result):
  3. if not cur.left and not cur.right:
  4. return True if result == 0 else False
  5. if cur.left:
  6. result -= cur.left.val
  7. if self.traversal(cur.left, result):
  8. return True
  9. result += cur.left.val # 回溯,将减去的值加回去
  10. if cur.right:
  11. result -= cur.right.val
  12. if self.traversal(cur.right, result):
  13. return True
  14. result += cur.right.val
  15. return False
  16. def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
  17. if not root:
  18. return False
  19. return self.traversal(root, targetSum - root.val)

本题也可采用迭代法,使用层次遍历来求解:

  1. class Solution:
  2. def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
  3. if not root:
  4. return False
  5. queue = deque([root])
  6. path = deque([root.val]) # 用另一个队列来存储路径值,便于回退
  7. count = 0
  8. while queue:
  9. for _ in range(len(queue)):
  10. node = queue.popleft()
  11. count = path.popleft()
  12. if not node.left and not node.right:
  13. if count == targetSum:
  14. return True
  15. if node.left:
  16. queue.append(node.left)
  17. path.append(count + node.left.val)
  18. if node.right:
  19. queue.append(node.right)
  20. path.append(count + node.right.val)
  21. return False

 113.路经总和Ⅱ

题目链接

  1. class Solution:
  2. def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
  3. result = []
  4. path = []
  5. self.traversal(root, targetSum, path, result)
  6. return result
  7. def traversal(self,node, count, path, result):
  8. if not node:
  9. return
  10. path.append(node.val)
  11. count -= node.val
  12. if not node.left and not node.right and count == 0:
  13. result.append(list(path))
  14. self.traversal(node.left, count, path, result)
  15. self.traversal(node.right, count, path, result)
  16. path.pop()

106.从中序与后序遍历序列构造二叉树 

题目链接

讲解链接

原理:以后序数组的最后一个元素为切割点,先切中序数组,根据中序数组,反过来再切后序数组。一层一层切下去,每次后序数组最后一个元素就是节点元素。

步骤:

1.若后序数组为0,返回空节点

2.后序数组的最后一个元素作为节点元素

3.在中序数组中寻找2.得到的节点元素作为切割点

4.切中序数组

5.切后序数组

6.递归处理左右区间

简而言之就是通过后序数组和中序数组来确定左右子树,进而切割得到左右子树的后序和中序数组,然后进行递归就能求出整个树。

  1. class Solution:
  2. def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:
  3. if not postorder: # 树为空则返回null
  4. return None
  5. root_val = postorder[-1] # 后序数组的最后一个值为根节点的值
  6. root = TreeNode(root_val) # 创建根节点
  7. index = inorder.index(root_val) # 查找根节点在中序数组中的位置
  8. left_inorder = inorder[:index] # 切割中序数组,构建左中序数组,即为左子树
  9. right_inorder = inorder[index+1:] # 切割中序数组,构建右中序数组,即为右子树
  10. left_postorder = postorder[:len(left_inorder)] # 切割后序数组,注意左后序数组和左中序数组的长度是一样的
  11. right_postorder = postorder[len(left_inorder):len(postorder)-1] # 切割后序数组
  12. root.left = self.buildTree(left_inorder, left_postorder) # 递归得到左子树
  13. root.right = self.buildTree(right_inorder, right_postorder) # 递归得到右子树
  14. return root # 返回结果

 105.从前序与中序遍历序列构造二叉树

题目链接

本题思路与前一题基本一致,只需要将对后序数组的处理改为前序数组对应的处理即可。

  1. class Solution:
  2. def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
  3. if not preorder:
  4. return None
  5. root_val = preorder[0]
  6. root = TreeNode(root_val)
  7. index = inorder.index(root_val)
  8. left_inorder = inorder[:index]
  9. right_inorder = inorder[index+1:]
  10. # 注意中序数组的长度和前序数组一定是一样的
  11. left_preorder = preorder[1:1+len(left_inorder)]
  12. right_preorder = preorder[1+len(left_inorder):]
  13. root.left = self.buildTree(left_preorder, left_inorder)
  14. root.right = self.buildTree(right_preorder, right_inorder)
  15. return root
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/302579
推荐阅读
相关标签
  

闽ICP备14008679号