代码随想录系列
上题
105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)
106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)
第一题
给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。
示例 1:
输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
输出: [3,9,20,null,null,15,7]
示例 2:
输入: preorder = [-1], inorder = [-1]
输出: [-1]
提示:
1 <= preorder.length <= 3000
inorder.length == preorder.length
-3000 <= preorder[i], inorder[i] <= 3000
preorder 和 inorder 均 无重复 元素
inorder 均出现在 preorder
preorder 保证 为二叉树的前序遍历序列
inorder 保证 为二叉树的中序遍历序列
思路
天冷不罗嗦,全在注释里
代码
import collections
class TreeNode:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
"""
给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。
示例 1:
输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
输出: [3,9,20,null,null,15,7]
示例 2:
输入: preorder = [-1], inorder = [-1]
输出: [-1]
提示:
1 <= preorder.length <= 3000
inorder.length == preorder.length
-3000 <= preorder[i], inorder[i] <= 3000
preorder 和 inorder 均 无重复 元素
inorder 均出现在 preorder
preorder 保证 为二叉树的前序遍历序列
inorder 保证 为二叉树的中序遍历序列
"""
def create_tree(self, root):
if not root:
return
result = TreeNode(root[0])
n, i = len(root), 1
queue = [result]
while queue and i < n:
node = queue.pop(0)
if i < n and root[i] != 'null':
root_node = TreeNode(root[i])
node.left = root_node
queue.append(root_node)
i += 1
if i < n and root[i] != 'null':
root_node = TreeNode(root[i])
node.right = root_node
queue.append(root_node)
i += 1
return result
def buildTree(self, preorder, inorder):
if not preorder or not inorder:
return None
# 核心要记住,前中后序遍历的左右子树列表长度是相等的,找到中序遍历的左右子树长度n即可用来找前后序遍历的左右子树,长度是一样的,只是顺序不一样
root = TreeNode(preorder[0])
# 获取当前节点在中序遍历的下标
n = inorder.index(preorder[0])
# 获取当前节点中序遍历的左右子树
in_left_tree = inorder[:n]
in_right_tree = inorder[n+1:]
# 获取当前节点在前序遍历的左右子树
pre_left_tree = preorder[1:n+1]
pre_right_tree = preorder[n+1:]
root.left = self.buildTree(pre_left_tree,in_left_tree)
root.right = self.buildTree(pre_right_tree,in_right_tree)
return root
def levelOrder(self, root: TreeNode) -> list:
if not root:
return []
result = []
root = [root]
# re = root
# root = collections.deque()
# root.append(re)
while root:
tem = []
for _ in range(len(root)):
node = root.pop(0)
# node = root.popleft()
tem.append(node.val)
if node.left:
root.append(node.left)
if node.right:
root.append(node.right)
result.append(tem)
# print(tem)
return result
if __name__ == '__main__':
test = Solution()
preorder = [[3, 9, 20, 15, 7], [-1]]
inorder = [[9, 3, 15, 20, 7], [-1]]
for i in range(len(preorder)):
tree_root = test.buildTree(preorder[i], inorder[i])
print(test.levelOrder(tree_root))
第二题
给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。
示例 1:
输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
输出: [3,9,20,null,null,15,7]
示例 2:
输入: preorder = [-1], inorder = [-1]
输出: [-1]
提示:
1 <= preorder.length <= 3000
inorder.length == preorder.length
-3000 <= preorder[i], inorder[i] <= 3000
preorder 和 inorder 均 无重复 元素
inorder 均出现在 preorder
preorder 保证 为二叉树的前序遍历序列
inorder 保证 为二叉树的中序遍历序列
思路
同第一题
代码
import collections
class TreeNode:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
"""
给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。
示例 1:
输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
输出: [3,9,20,null,null,15,7]
示例 2:
输入: preorder = [-1], inorder = [-1]
输出: [-1]
提示:
1 <= preorder.length <= 3000
inorder.length == preorder.length
-3000 <= preorder[i], inorder[i] <= 3000
preorder 和 inorder 均 无重复 元素
inorder 均出现在 preorder
preorder 保证 为二叉树的前序遍历序列
inorder 保证 为二叉树的中序遍历序列
"""
def create_tree(self, root):
if not root:
return None
result = TreeNode(root[0])
n, i = len(root), 1
queue = [result]
while queue and i < n:
node = queue.pop(0)
if i < n and root[i] != 'null':
root_node = TreeNode(root[i])
node.left = root_node
queue.append(root_node)
i += 1
if i < n and root[i] != 'null':
root_node = TreeNode(root[i])
node.right = root_node
queue.append(root_node)
i += 1
return result
def buildTree(self, inorder, postorder):
if not inorder or not postorder:
return
# 获取当前树结点----后序遍历的最后一个值
root = TreeNode(postorder[-1])
# 获取当前节点在中序遍历的下标
n = inorder.index(postorder[-1])
# 获取当前节点在中序遍历的左右子树
in_left_tree = inorder[:n]
in_right_tree = inorder[n + 1:]
# 获取当前节点在后序遍历的左右子树,首先排除掉最后一个结点,中序、后序遍历的左右子树长度相等,可以中序遍历的结果来确定后序遍历的左右子树
po_left_tree = postorder[:n]
po_right_tree = postorder[n:-1]
# 递归遍历左右子树
root.left = self.buildTree(in_left_tree, po_left_tree)
root.right = self.buildTree(in_right_tree, po_right_tree)
return root
def levelOrder(self, root: TreeNode) -> list:
if not root:
return []
result = []
root = [root]
# re = root
# root = collections.deque()
# root.append(re)
while root:
tem = []
for _ in range(len(root)):
node = root.pop(0)
# node = root.popleft()
tem.append(node.val)
if node.left:
root.append(node.left)
if node.right:
root.append(node.right)
result.append(tem)
# print(tem)
return result
if __name__ == '__main__':
test = Solution()
preorder = [[9, 3, 15, 20, 7], [-1]]
postorder = [[9, 15, 7, 20, 3], [-1]]
for i in range(len(preorder)):
tree_root = test.buildTree(preorder[i], postorder[i])
print(test.levelOrder(tree_root))
第三题
给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。
叶子节点 是指没有子节点的节点。
示例 1:
输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
输出:true
解释:等于目标和的根节点到叶节点路径如上图所示。
示例 2:
输入:root = [1,2,3], targetSum = 5
输出:false
解释:树中存在两条根节点到叶子节点的路径:
(1 --> 2): 和为 3
(1 --> 3): 和为 4
不存在 sum = 5 的根节点到叶子节点的路径。
示例 3:
输入:root = [], targetSum = 0
输出:false
解释:由于树是空的,所以不存在根节点到叶子节点的路径。
思路
- 用一个变量记录经过路径的结点和
- 遇到叶子节点(没有左右子树)则把路径和加入结果列表
- 遇到非叶子节点累加后递归
代码
class TreeNode:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
"""
给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。
叶子节点 是指没有子节点的节点。
示例 1:
输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
输出:true
解释:等于目标和的根节点到叶节点路径如上图所示。
示例 2:
输入:root = [1,2,3], targetSum = 5
输出:false
解释:树中存在两条根节点到叶子节点的路径:
(1 --> 2): 和为 3
(1 --> 3): 和为 4
不存在 sum = 5 的根节点到叶子节点的路径。
示例 3:
输入:root = [], targetSum = 0
输出:false
解释:由于树是空的,所以不存在根节点到叶子节点的路径。
"""
def create_tree(self, root):
if not root:
return None
result = TreeNode(root[0])
n, i = len(root), 1
queue = [result]
while queue and i < n:
node = queue.pop(0)
if i < n and root[i] != 'null':
root_node = TreeNode(root[i])
node.left = root_node
queue.append(root_node)
i += 1
if i < n and root[i] != 'null':
root_node = TreeNode(root[i])
node.right = root_node
queue.append(root_node)
i += 1
return result
def hasPathSum(self, root, targetSum):
self.result = []
def dfs(root, re):
if not root:
return
if not root.left and not root.right:
re += int(root.val)
self.result.append(re)
return
else:
re += int(root.val)
dfs(root.left, re)
dfs(root.right, re)
dfs(root, 0)
for i in self.result:
if i == targetSum:
return True
return False
if __name__ == '__main__':
test = Solution()
root = [[5, 4, 8, 11, 'null', 13, 4, 7, 2, 'null', 'null', 'null', 1], [1, 2, 3], []]
targetSum = [22, 5, 0]
for i in range(len(root)):
tree = test.create_tree(root[i])
print(test.hasPathSum(tree, targetSum[i]))
第四题
给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。
叶子节点 是指没有子节点的节点。
示例 1:
输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:[[5,4,11,2],[5,8,4,5]]
示例 2:
输入:root = [1,2,3], targetSum = 5
输出:[]
示例 3:
输入:root = [1,2], targetSum = 0
输出:[]
提示:
树中节点总数在范围 [0, 5000] 内
-1000 <= Node.val <= 1000
-1000 <= targetSum <= 1000
思路
基本没啥变化,就是遇到叶子节点的时候累加路径的结点和,满足条件则把路径加入结果列表即可
代码
class TreeNode:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
"""
给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。
叶子节点 是指没有子节点的节点。
示例 1:
输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:[[5,4,11,2],[5,8,4,5]]
示例 2:
输入:root = [1,2,3], targetSum = 5
输出:[]
示例 3:
输入:root = [1,2], targetSum = 0
输出:[]
提示:
树中节点总数在范围 [0, 5000] 内
-1000 <= Node.val <= 1000
-1000 <= targetSum <= 1000
"""
def create_tree(self, root):
if not root:
return None
result = TreeNode(root[0])
n, i = len(root), 1
queue = [result]
while queue and i < n:
node = queue.pop(0)
if i < n and root[i] != 'null':
root_node = TreeNode(root[i])
node.left = root_node
queue.append(root_node)
i += 1
if i < n and root[i] != 'null':
root_node = TreeNode(root[i])
node.right = root_node
queue.append(root_node)
i += 1
return result
def pathSum(self, root, targetSum):
result = []
def dfs(root,path):
if not root:
return
if not root.left and not root.right:
path.append(root.val)
if sum(path) == targetSum:
result.append(list(path))
path.pop()
return
else:
path.append(root.val)
dfs(root.left, path)
dfs(root.right, path)
path.pop()
dfs(root, [])
return result
if __name__ == '__main__':
test = Solution()
root = [[5, 4, 8, 11, 'null', 13, 4, 7, 2, 'null', 'null', 5, 1], [1, 2, 3], []]
targetSum = [22, 5, 0]
for i in range(len(root)):
tree = test.create_tree(root[i])
print(test.pathSum(tree, targetSum[i]))
第五题
class TreeNode:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
"""
给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。
假设二叉树中至少有一个节点。
示例 1:
输入: root = [2,1,3]
输出: 1
示例 2:
输入: [1,2,3,4,null,5,6,null,null,7]
输出: 7
提示:
二叉树的节点个数的范围是 [1,104]
-231 <= Node.val <= 231 - 1
"""
def create_tree(self, root):
if not root:
return None
result = TreeNode(root[0])
n, i = len(root), 1
queue = [result]
while queue and i < n:
node = queue.pop(0)
if i < n and root[i] != 'null':
root_node = TreeNode(root[i])
node.left = root_node
queue.append(root_node)
i += 1
if i < n and root[i] != 'null':
root_node = TreeNode(root[i])
node.right = root_node
queue.append(root_node)
i += 1
return result
def findBottomLeftValue1(self, root) -> int:
result = []
def dfs(root, depth):
if not root:
return
if len(result) == depth:
result.append(root.val)
dfs(root.left, depth + 1)
dfs(root.right, depth + 1)
dfs(root, 0)
return result[-1]
def findBottomLeftValue(self, root):
if not root:
return None
queue = [root]
while queue:
node = queue.pop(0)
if node.right:
queue.append(node.right)
if node.left:
queue.append(node.left)
return node.val
if __name__ == '__main__':
test = Solution()
root = [[2, 1, 3], [1, 2, 3, 4, 'null', 5, 6, 'null', 'null', 7]]
for i in root:
tree = test.create_tree(i)
print(test.findBottomLeftValue(tree))
print(test.findBottomLeftValue1(tree))
思路
换种说法就是求左视图的最后一个节点值,和右视图相反
代码随想录Day12 二叉树层序遍历| Leetcode十题-CSDN博客
代码
class TreeNode:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
"""
给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。
假设二叉树中至少有一个节点。
示例 1:
输入: root = [2,1,3]
输出: 1
示例 2:
输入: [1,2,3,4,null,5,6,null,null,7]
输出: 7
提示:
二叉树的节点个数的范围是 [1,104]
-231 <= Node.val <= 231 - 1
"""
def create_tree(self, root):
if not root:
return None
result = TreeNode(root[0])
n, i = len(root), 1
queue = [result]
while queue and i < n:
node = queue.pop(0)
if i < n and root[i] != 'null':
root_node = TreeNode(root[i])
node.left = root_node
queue.append(root_node)
i += 1
if i < n and root[i] != 'null':
root_node = TreeNode(root[i])
node.right = root_node
queue.append(root_node)
i += 1
return result
def findBottomLeftValue1(self, root) -> int:
result = []
def dfs(root, depth):
if not root:
return
if len(result) == depth:
result.append(root.val)
dfs(root.left, depth + 1)
dfs(root.right, depth + 1)
dfs(root, 0)
return result[-1]
def findBottomLeftValue(self, root):
if not root:
return None
queue = [root]
while queue:
node = queue.pop(0)
if node.right:
queue.append(node.right)
if node.left:
queue.append(node.left)
return node.val
if __name__ == '__main__':
test = Solution()
root = [[2, 1, 3], [1, 2, 3, 4, 'null', 5, 6, 'null', 'null', 7]]
for i in root:
tree = test.create_tree(i)
print(test.findBottomLeftValue(tree))
print(test.findBottomLeftValue1(tree))
总结
这天好冷。。。。