前言
整理了下二叉树遍历相关的题目,大概40道左右。所有的题目都是使用前序、中序、后序的递归、迭代法;层次遍历的迭代法。熟练使用这七种框架式的写法,在框架之上修改下逻辑,80%的二叉树的题目都可以解决。
一、前序遍历
1.0、前序框架模板
leetcode144. 二叉树的前序遍历
144. 二叉树的前序遍历
递归写法
class Solution(object):
def preorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
res = []
def dfs(node):
if not node:
return
res.append(node.val)
dfs(node.left)
dfs(node.right)
dfs(root)
return res
迭代写法
class Solution(object):
def preorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
res = []
stack, cur = [], root
while stack or cur:
while cur:
stack.append(cur)
res.append(cur.val)
cur = cur.left
cur = stack.pop()
cur = cur.right
return res
1.1、经典题目
要点
1、找到叶子节点:if not node.left and not node.right 2、找到左叶子节点:if node.left and not node.left.left and not node.left.right 3、找到最大深度的第一个叶子节点: if not node.left and not node.right and curDepth > maxDepth
leetcode257. 二叉树的所有路径
257. 二叉树的所有路径:前序
class Solution:
def binaryTreePaths(self, root: TreeNode) -> List[str]:
res = []
def dfs(node, path):
if not node: return
if not node.left and not node.right:
res.append(path + str(node.val))
dfs(node.left, path + str(node.val) + '->')
dfs(node.right, path + str(node.val) + '->')
dfs(root, '')
return res
leetcode226. 翻转二叉树
226. 翻转二叉树 = 剑指 Offer 27. 二叉树的镜像:前序 / 层次
class Solution:
def invertTree(self, root: TreeNode) -> TreeNode:
def dfs(node):
if not node: return
node.left, node.right = node.right, node.left
dfs(node.left)
dfs(node.right)
dfs(root)
return root
if not root: return None
queue = [root]
while queue:
cur = queue.pop(0)
cur.left, cur.right = cur.right, cur.left
if cur.left: queue.append(cur.left)
if cur.right: queue.append(cur.right)
return root
leetcode129. 求根节点到叶节点数字之和
129. 求根节点到叶节点数字之和:前序
class Solution:
def sumNumbers(self, root: TreeNode) -> int:
res = 0
def dfs(node, path_sum):
nonlocal res
if not node: return
if not node.left and not node.right:
res += path_sum * 10 + node.val
dfs(node.left, path_sum * 10 + node.val)
dfs(node.right, path_sum * 10 + node.val)
dfs(root, 0)
return res
leetcode404. 左叶子之和
404. 左叶子之和: 前序
class Solution:
def sumOfLeftLeaves(self, root: TreeNode) -> int:
res = 0
def dfs(node):
nonlocal res
if not node: return
if node.left and not node.left.left and not node.left.right:
res += node.left.val
dfs(node.left)
dfs(node.right)
dfs(root)
return res
leetcode513. 找树左下角的值
513. 找树左下角的值:层次 / 前序
class Solution:
def findBottomLeftValue(self, root: TreeNode) -> int:
queue = [root]
res = root.val
while queue:
size = len(queue)
for i in range(size):
cur = queue.pop(0)
if i == 0: res = cur.val
if cur.left: queue.append(cur.left)
if cur.right: queue.append(cur.right)
return res
maxDepth, mostLeft = 0, root.val
def dfs(node, curDepth):
nonlocal maxDepth, mostLeft
if not node: return
if not node.left and not node.right and curDepth > maxDepth:
maxDepth = curDepth
mostLeft = node.val
dfs(node.left, curDepth + 1)
dfs(node.right, curDepth + 1)
dfs(root, 0)
return mostLeft
leetcode112. 路径总和
112. 路径总和:前序
class Solution:
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
has_path = False
def dfs(node, path_sum):
nonlocal has_path
if not node: return
if not node.left and not node.right:
if path_sum + node.val == targetSum:
has_path = True
return
dfs(node.left, path_sum + node.val)
dfs(node.right, path_sum + node.val)
dfs(root, 0)
return has_path
leetcode113. 路径总和 II
113. 路径总和 II: 前序
class Solution:
def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
res = []
def dfs(node, path_sum, path):
if not node: return
if not node.left and not node.right:
if path_sum + node.val == targetSum:
path.append(node.val)
res.append(path)
dfs(node.left, path_sum + node.val, path + [node.val])
dfs(node.right, path_sum + node.val, path + [node.val])
dfs(root, 0, [])
return res
leetcode437. 路径总和 III
437. 路径总和 III:前序 / 前缀和
class Solution:
def pathSum(self, root: TreeNode, targetSum: int) -> int:
if not root: return 0
def dfs(node, path_num):
if not node: return 0
res = 0
if path_num + node.val == targetSum:
res += 1
res += dfs(node.left, path_num + node.val)
res += dfs(node.right, path_num + node.val)
return res
return dfs(root, 0) + self.pathSum(root.left, targetSum) + self.pathSum(root.right, targetSum)
二、中序遍历
2.0、中序框架模板
leetcode94. 二叉树的中序遍历
94. 二叉树的中序遍历
递归写法和迭代写法
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
res = []
def dfs_in(node):
nonlocal res
if not node: return
dfs_in(node.left)
res.append(node.val)
dfs_in(node.right)
dfs_in(root)
return res
stack, cur = [], root
res = []
while stack or cur:
while cur:
stack.append(cur)
cur = cur.left
cur = stack.pop()
res.append(cur.val)
cur = cur.right
return res
2.1、经典题目
中序遍历的一个大应用就是和二叉搜索树结合起来的。
leetcode98. 验证二叉搜索树
98. 验证二叉搜索树
class Solution:
def isValidBST(self, root: TreeNode) -> bool:
stack, cur = [], root
preValue = float('-inf')
while stack or cur:
while cur:
stack.append(cur)
cur = cur.left
cur = stack.pop()
if cur.val <= preValue:
return False
preValue = cur.val
cur = cur.right
return True
preValue = float('-inf')
res = True
def dfs_in(node):
nonlocal preValue, res
if not node: return
dfs_in(node.left)
if node.val <= preValue:
res = False
return
preValue = node.val
dfs_in(node.right)
dfs_in(root)
return res
leetcode230. 二叉搜索树中第K小的元素
230. 二叉搜索树中第K小的元素
class Solution:
def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:
stack, cur = [], root
while stack or cur:
while cur:
stack.append(cur)
cur = cur.left
cur = stack.pop()
k -= 1
if k == 0: return cur.val
cur = cur.right
leetcode剑指 Offer 54. 二叉搜索树的第k大节点
剑指 Offer 54. 二叉搜索树的第k大节点
和上一题差不多,从小到大遍历换成从大到小遍历即可。
class Solution:
def kthLargest(self, root: TreeNode, k: int) -> int:
stack, cur = [], root
while stack or cur:
while cur:
stack.append(cur)
cur = cur.right
cur = stack.pop()
k -= 1
if k == 0: return cur.val
cur = cur.left
leetcode530. 二叉搜索树的最小绝对差
530. 二叉搜索树的最小绝对差
class Solution:
def getMinimumDifference(self, root: TreeNode) -> int:
minV = float('inf')
preV = float('inf')
stack, cur = [], root
while stack or cur:
while cur:
stack.append(cur)
cur = cur.left
cur = stack.pop()
curV = abs(cur.val - preV)
if curV < minV:
minV = curV
preV = cur.val
cur = cur.right
return minV
leetcode501. 二叉搜索树中的众数
501. 二叉搜索树中的众数
class Solution:
def findMode(self, root: TreeNode) -> List[int]:
stack, cur = [], root
count_dict = defaultdict(int)
maxCount = 0
while stack or cur:
while cur:
stack.append(cur)
cur = cur.left
cur = stack.pop()
count_dict[cur.val] += 1
if count_dict[cur.val] > maxCount:
maxCount = count_dict[cur.val]
cur = cur.right
return [k for k, v in count_dict.items() if v == maxCount]
上面只写了一种先统计再更新的中序遍历方法,还有一种边统计边更新的方法,有想法的可以自己看下:
leetcode538. 把二叉搜索树转换为累加树
538. 把二叉搜索树转换为累加树
class Solution:
def convertBST(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
stack, cur = [], root
count = 0
while stack or cur:
while cur:
stack.append(cur)
cur = cur.right
cur = stack.pop()
count += cur.val
cur.val = count
cur = cur.left
return root
leetcode426. 将二叉搜索树转化为排序的双向链表
剑指 Offer 36. 二叉搜索树与双向链表 = 426. 将二叉搜索树转化为排序的双向链表(重要)
"""
# Definition for a Node.
class Node:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
"""
class Solution:
def treeToDoublyList(self, root: 'Node') -> 'Node':
if not root: return None
stack, cur = [], root
pre, head = None, None
while stack or cur:
while cur:
stack.append(cur)
cur = cur.left
cur = stack.pop()
if not pre:
head = cur
else:
pre.right = cur
cur.left = pre
pre = cur
cur = cur.right
pre.right = head
head.left = pre
return head
三、后序遍历
3.0、后序框架模板
leetcode145. 二叉树的后序遍历
145. 二叉树的后序遍历
递归写法
class Solution:
def postorderTraversal(self, root: TreeNode) -> List[int]:
res = []
def dfs(node):
if not node: return
dfs(node.left)
dfs(node.right)
res.append(node.val)
dfs(root)
return res
迭代写法
class Solution:
def postorderTraversal(self, root: TreeNode) -> List[int]:
stack, cur = [], root
res = []
while stack or cur:
while cur:
stack.append(cur)
res.append(cur.val)
cur = cur.right
cur = stack.pop()
cur = cur.left
return res[::-1]
3.1、经典题目
leetcode226. 翻转二叉树
226. 翻转二叉树
这道题可以用层次遍历、前序遍历、后序遍历三种方法。但是唯独不能用中序遍历,因为根据左根右的顺序,在遍历根的时候,如果调换左右节点,顺序就会乱掉。
class Solution:
def invertTree(self, root: TreeNode) -> TreeNode:
def dfs(node):
if not node: return
node.left, node.right = node.right, node.left
dfs(node.left)
dfs(node.right)
dfs(root)
return root
if not root: return None
queue = [root]
while queue:
cur = queue.pop(0)
cur.left, cur.right = cur.right, cur.left
if cur.left: queue.append(cur.left)
if cur.right: queue.append(cur.right)
return root
def dfs(node):
if not node: return
dfs(node.left)
dfs(node.right)
node.left, node.right = node.right, node.left
dfs(root)
return root
leetcode104. 二叉树的最大深度
104. 二叉树的最大深度
这道题可以用层次遍历、前序遍历、中序遍历、后序遍历四种方法。
class Solution:
def maxDepth(self, root: TreeNode) -> int:
if not root: return 0
queue = [root]
depth = 0
while queue:
size = len(queue)
while size:
cur = queue.pop(0)
if cur.left: queue.append(cur.left)
if cur.right: queue.append(cur.right)
size -= 1
depth += 1
return depth
if not root: return 0
maxDepth = 1
def dfs(node, curDepth):
nonlocal maxDepth
if not node: return
if not node.left and not node.right and curDepth > maxDepth:
maxDepth = curDepth
dfs(node.left, curDepth + 1)
dfs(node.right, curDepth + 1)
dfs(root, 1)
return maxDepth
if not root: return 0
maxDepth = 1
def dfs(node, curDepth):
nonlocal maxDepth
if not node: return
dfs(node.left, curDepth + 1)
if not node.left and not node.right and curDepth > maxDepth:
maxDepth = curDepth
dfs(node.right, curDepth + 1)
dfs(root, 1)
return maxDepth
if not root: return 0
maxDepth = 1
def dfs(node, curDepth):
nonlocal maxDepth
if not node: return
dfs(node.left, curDepth + 1)
dfs(node.right, curDepth + 1)
if not node.left and not node.right and curDepth > maxDepth:
maxDepth = curDepth
dfs(root, 1)
return maxDepth
def dfs(node):
if not node: return 0
leftD = dfs(node.left)
rightD = dfs(node.right)
return max(leftD, rightD) + 1
return dfs(root)
leetcode559. N 叉树的最大深度
559. N 叉树的最大深度
这道题有前序、后序、层次遍历三种解法。没用中序遍历,因为N叉树没有中序而言。
"""
# Definition for a Node.
class Node:
def __init__(self, val=None, children=None):
self.val = val
self.children = children
"""
class Solution:
def maxDepth(self, root: 'Node') -> int:
if not root: return 0
maxD = float('-inf')
def dfs(node, curD):
nonlocal maxD
if not node: return 0
if not node.children and curD > maxD:
maxD = curD
for c in node.children:
dfs(c, curD + 1)
dfs(root, 1)
return maxD
if not root: return 0
maxD = float('-inf')
def dfs(node, curD):
nonlocal maxD
if not node: return 0
for c in node.children:
dfs(c, curD + 1)
if not node.children and curD > maxD:
maxD = curD
dfs(root, 1)
return maxD
if not root: return 0
queue, depth = [root], 0
while queue:
size = len(queue)
while size:
cur = queue.pop(0)
for c in cur.children:
queue.append(c)
size -= 1
depth += 1
return depth
leetcode111. 二叉树的最小深度
111. 二叉树的最小深度
这道题和上面的 104. 二叉树的最大深度 差不多,将 maxDepth 改成 minDepth 即可,同样有前、中、后、层次遍历4种方法。
class Solution:
def minDepth(self, root: TreeNode) -> int:
if not root: return 0
queue = [root]
depth = 1
while queue:
size = len(queue)
while size:
cur = queue.pop(0)
if not cur.left and not cur.right:
return depth
if cur.left: queue.append(cur.left)
if cur.right: queue.append(cur.right)
size -= 1
depth += 1
if not root: return 0
minD = float('inf')
def dfs(node, curD):
nonlocal minD
if not node: return 0
if not node.left and not node.right and curD < minD:
minD = curD
dfs(node.left, curD + 1)
dfs(node.right, curD + 1)
dfs(root, 1)
return minD
if not root: return 0
minD = float('inf')
def dfs(node, curD):
nonlocal minD
if not node: return 0
dfs(node.left, curD + 1)
if not node.left and not node.right and curD < minD:
minD = curD
dfs(node.right, curD + 1)
dfs(root, 1)
return minD
if not root: return 0
minD = float('inf')
def dfs(node, curD):
nonlocal minD
if not node: return 0
dfs(node.left, curD + 1)
dfs(node.right, curD + 1)
if not node.left and not node.right and curD < minD:
minD = curD
dfs(root, 1)
return minD
leetcode543. 二叉树的直径 (重要)
543. 二叉树的直径 (重要)
这道题必须使用后序遍历,因为要想得到最长直径,必须从叶子节点往上算,计算每个节点的左右哪条路径最长。
class Solution:
def diameterOfBinaryTree(self, root: TreeNode) -> int:
max_path = 0
def dfs_post(node):
nonlocal max_path
if not node: return 0
leftD = dfs_post(node.left)
rightD = dfs_post(node.right)
max_path = leftD + rightD + 1
return max(leftD, rightD) + 1
dfs_post(root)
return max_path - 1
leetcode124. 二叉树中的最大路径和(重要)
124. 二叉树中的最大路径和(重要)
这道题和上一道题很像,一样的套路。
class Solution:
def maxPathSum(self, root: TreeNode) -> int:
maxSum = float('-inf')
def dfs_post(node):
nonlocal maxSum
if not node: return 0
leftMax = max(dfs_post(node.left), 0)
rightMax = max(dfs_post(node.right), 0)
maxSum = max(leftMax + rightMax + node.val, maxSum)
return max(leftMax, rightMax) + node.val
dfs_post(root)
return maxSum
leetcode222. 完全二叉树的节点个数
222. 完全二叉树的节点个数
class Solution:
def countNodes(self, root: TreeNode) -> int:
if not root: return 0
queue = [root]
count = 0
while queue:
cur = queue.pop(0)
if cur.left: queue.append(cur.left)
if cur.right: queue.append(cur.right)
count += 1
return count
count = 0
def dfs(node):
nonlocal count
if not node: return
count += 1
dfs(node.left)
dfs(node.right)
dfs(root)
return count
count = 0
def dfs(node):
nonlocal count
if not node: return
dfs(node.left)
count += 1
dfs(node.right)
dfs(root)
return count
count = 0
def dfs(node):
nonlocal count
if not node: return
dfs(node.left)
dfs(node.right)
count += 1
dfs(root)
return count
if not root: return 0
def getH(node):
height = 0
while node:
height += 1
node = node.left
return height
leftH, rightH = getH(root.left), getH(root.right)
if leftH == rightH:
return 2**leftH - 1 + self.countNodes(root.right) + 1
else:
return self.countNodes(root.left) + 2**rightH - 1 + 1
leetcode814. 二叉树剪枝
814. 二叉树剪枝
class Solution:
def pruneTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
if not root: return None
def has_one(node):
if not node: return False
left = has_one(node.left)
right = has_one(node.right)
if left == False: node.left = None
if right == False: node.right = None
return True if left or right or node.val == 1 else False
return root if has_one(root) else None
leetcode110. 平衡二叉树(重要 经典)
110. 平衡二叉树(重要 经典)
class Solution:
def isBalanced(self, root: TreeNode) -> bool:
if not root: return True
def height(node):
if not node: return 0
leftH = height(node.left)
rightH = height(node.right)
return max(leftH, rightH) + 1
left, right = height(root.left), height(root.right)
return abs(left - right) <= 1 and self.isBalanced(root.left) and self.isBalanced(root.right)
def balance(node):
if not node: return 0
left = balance(node.left)
if left == - 1: return -1
right = balance(node.right)
if right == -1: return -1
return max(left, right) + 1 if abs(left - right) <= 1 else -1
return isBalanced(node) != -1
leetcode236. 二叉树的最近公共祖先(很重要 难点 经典)
236. 二叉树的最近公共祖先(很重要 难点 经典)
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
def dfs_pre(node, path, targt, res):
if not node: return
if node == targt:
path.append(node)
res.extend(path)
return
dfs_pre(node.left, path + [node], targt, res)
dfs_pre(node.right, path + [node], targt, res)
path_p, path_q = [], []
lowest = root
dfs_pre(root, [], p, path_p)
dfs_pre(root, [], q, path_q)
for u, v in zip(path_p, path_q):
if u == v:
lowest = u
return lowest
四、层次遍历
4.0、层次框架模板
leetcode102. 二叉树的层序遍历
102. 二叉树的层序遍历
一层一层输出:[ [3],[9,20],[15,7] ]
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
if not root: return []
res, queue = [], [root]
while queue:
arr, size = [], len(queue)
while size:
cur = queue.pop(0)
arr.append(cur.val)
if cur.left: queue.append(cur.left)
if cur.right: queue.append(cur.right)
size -= 1
res.append(arr)
return res
简化版输出输出:[3,9,20,15,7]
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
res, queue = [], [root]
while queue:
cur = queue.pop(0)
res.append(cur.val)
if cur.left: queue.append(cur.left)
if cur.right: queue.append(cur.right)
return res
4.1、经典题目
leetcode107. 二叉树的层序遍历 II
107. 二叉树的层序遍历 II
class Solution:
def levelOrderBottom(self, root: TreeNode) -> List[List[int]]:
if not root: return []
res, queue = [], [root]
while queue:
arr, size = [], len(queue)
while size:
cur = queue.pop(0)
arr.append(cur.val)
if cur.left: queue.append(cur.left)
if cur.right: queue.append(cur.right)
size -= 1
res.append(arr)
return res[::-1]
leetcode103. 二叉树的锯齿形层序遍历
103. 二叉树的锯齿形层序遍历
class Solution:
def zigzagLevelOrder(self, root: TreeNode) -> List[List[int]]:
if not root: return []
queue, res = [root], []
level = 1
while queue:
size, arr = len(queue), []
while size:
cur = queue.pop(0)
arr.append(cur.val)
if cur.left: queue.append(cur.left)
if cur.right: queue.append(cur.right)
size -= 1
if level % 2 == 0:
arr = arr[::-1]
res.append(arr)
level += 1
return res
leetcode513. 找树左下角的值
513. 找树左下角的值:层次 / 前序
class Solution:
def findBottomLeftValue(self, root: TreeNode) -> int:
queue = [root]
res = root.val
while queue:
size = len(queue)
for i in range(size):
cur = queue.pop(0)
if i == 0: res = cur.val
if cur.left: queue.append(cur.left)
if cur.right: queue.append(cur.right)
return res
maxDepth, mostLeft = 0, root.val
def dfs(node, curDepth):
nonlocal maxDepth, mostLeft
if not node: return
if not node.left and not node.right and curDepth > maxDepth:
maxDepth = curDepth
mostLeft = node.val
dfs(node.left, curDepth + 1)
dfs(node.right, curDepth + 1)
dfs(root, 0)
return mostLeft
leetcode104. 二叉树的最大深度
104. 二叉树的最大深度: 层次 / 前序
class Solution:
def maxDepth(self, root: TreeNode) -> int:
if not root: return 0
queue = [root]
depth = 0
while queue:
size = len(queue)
while size:
cur = queue.pop(0)
if cur.left: queue.append(cur.left)
if cur.right: queue.append(cur.right)
size -= 1
depth += 1
return depth
if not root: return 0
maxDepth = 1
def dfs(node, curDepth):
nonlocal maxDepth
if not node: return
if not node.left and not node.right and curDepth > maxDepth:
maxDepth = curDepth
dfs(node.left, curDepth + 1)
dfs(node.right, curDepth + 1)
dfs(root, 1)
return maxDepth
if not root: return 0
maxDepth = 1
def dfs(node, curDepth):
nonlocal maxDepth
if not node: return
dfs(node.left, curDepth + 1)
if not node.left and not node.right and curDepth > maxDepth:
maxDepth = curDepth
dfs(node.right, curDepth + 1)
dfs(root, 1)
return maxDepth
if not root: return 0
maxDepth = 1
def dfs(node, curDepth):
nonlocal maxDepth
if not node: return
dfs(node.left, curDepth + 1)
dfs(node.right, curDepth + 1)
if not node.left and not node.right and curDepth > maxDepth:
maxDepth = curDepth
dfs(root, 1)
return maxDepth
def dfs(node):
if not node: return 0
leftD = dfs(node.left)
rightD = dfs(node.right)
return max(leftD, rightD) + 1
return dfs(root)
leetcode111. 二叉树的最小深度
111. 二叉树的最小深度
class Solution:
def minDepth(self, root: TreeNode) -> int:
if not root: return 0
queue = [root]
depth = 1
while queue:
size = len(queue)
while size:
cur = queue.pop(0)
if not cur.left and not cur.right:
return depth
if cur.left: queue.append(cur.left)
if cur.right: queue.append(cur.right)
size -= 1
depth += 1
leetcode515. 在每个树行中找最大值
515. 在每个树行中找最大值
class Solution:
def largestValues(self, root: TreeNode) -> List[int]:
if not root: return []
res, queue = [], [root]
while queue:
size, levelMax = len(queue), float('-inf')
while size:
cur = queue.pop(0)
if cur.val > levelMax:
levelMax = cur.val
if cur.left: queue.append(cur.left)
if cur.right: queue.append(cur.right)
size -= 1
res.append(levelMax)
return res
leetcode199. 二叉树的右视图
199. 二叉树的右视图
class Solution:
def rightSideView(self, root: TreeNode) -> List[int]:
if not root: return []
res, queue = [], [root]
while queue:
size = len(queue)
while size:
cur = queue.pop(0)
if size == 1:
res.append(cur.val)
if cur.left: queue.append(cur.left)
if cur.right: queue.append(cur.right)
size -= 1
return res
leetcode637. 二叉树的层平均值
637. 二叉树的层平均值
class Solution:
def averageOfLevels(self, root: Optional[TreeNode]) -> List[float]:
if not root: return []
res, queue = [], [root]
while queue:
size, sumValue = len(queue), 0
count = size
while size:
cur = queue.pop(0)
sumValue += cur.val
if cur.left: queue.append(cur.left)
if cur.right: queue.append(cur.right)
size -= 1
res.append(sumValue / count)
return res
leetcode429. N 叉树的层序遍历
429. N 叉树的层序遍历
"""
# Definition for a Node.
class Node:
def __init__(self, val=None, children=None):
self.val = val
self.children = children
"""
class Solution:
def levelOrder(self, root: 'Node') -> List[List[int]]:
if not root: return []
res, queue = [], [root]
while queue:
size, arr = len(queue), []
while size:
cur = queue.pop(0)
arr.append(cur.val)
for c in cur.children:
queue.append(c)
size -= 1
res.append(arr)
return res
leetcode226. 翻转二叉树
226. 翻转二叉树
class Solution:
def invertTree(self, root: TreeNode) -> TreeNode:
def dfs(node):
if not node: return
node.left, node.right = node.right, node.left
dfs(node.left)
dfs(node.right)
dfs(root)
return root
if not root: return None
queue = [root]
while queue:
cur = queue.pop(0)
cur.left, cur.right = cur.right, cur.left
if cur.left: queue.append(cur.left)
if cur.right: queue.append(cur.right)
return root
leetcode剑指 Offer 28. 对称的二叉树
剑指 Offer 28. 对称的二叉树: 递归 / 层次
这道题的层次遍历的框架和以往的题目有一点的差别,不是很大,要注意一下
class Solution:
def isSymmetric(self, root: TreeNode) -> bool:
def isMirror(A, B):
if not A and not B: return True
if not A or not B: return False
if A.val != B.val: return False
return isMirror(A.left, B.right) and isMirror(A.right, B.left)
return isMirror(root.left, root.right) if root else True
queue = [root]
while queue:
size, arr = len(queue), []
count = size
while size:
cur = queue.pop(0)
if cur:
arr.append(cur.val)
else:
arr.append('#')
if cur:
queue.append(cur.left)
queue.append(cur.right)
size -= 1
for i in range(count // 2):
if arr[i] != arr[~i]:
return False
return True
leetcode958. 二叉树的完全性检验(判断一颗二叉树是否是完全二叉树)
958. 二叉树的完全性检验(判断一颗二叉树是否是完全二叉树)
class Solution:
def isCompleteTree(self, root: TreeNode) -> bool:
queue = [root]
while queue:
cur = queue.pop(0)
if not cur:
break
queue.append(cur.left)
queue.append(cur.right)
for q in queue:
if q: return False
return True
leetcode116. 填充每个节点的下一个右侧节点指针
116. 填充每个节点的下一个右侧节点指针:层次 / 穿针引线(很精彩的方法)
"""
# Definition for a Node.
class Node:
def __init__(self, val: int = 0, left: 'Node' = None, right: 'Node' = None, next: 'Node' = None):
self.val = val
self.left = left
self.right = right
self.next = next
"""
class Solution:
def connect(self, root: 'Node') -> 'Node':
if not root: return None
queue = [root]
while queue:
size = len(queue)
while size:
cur = queue.pop(0)
if size > 1:
cur.next = queue[0]
if cur.left: queue.append(cur.left)
if cur.right: queue.append(cur.right)
size -= 1
return root
if not root: return None
leftMost = root
while leftMost.left:
head = leftMost
while head:
head.left.next = head.right
if head.next:
head.right.next = head.next.left
head = head.next
leftMost = leftMost.left
return root
leetcode117. 填充每个节点的下一个右侧节点指针 II
117. 填充每个节点的下一个右侧节点指针 II:层次 / 穿针引线(很重要 暂时没弄很懂)
这两道题如果用层次遍历解决的话,其实是一样的。但是用穿针引线的话,这道题有点难度,不知道怎么找到每层的最左边元素,因为这个二叉树不是完全二叉树,不好找。
"""
"""
class Node:
def __init__(self, val: int = 0, left: 'Node' = None, right: 'Node' = None, next: 'Node' = None):
self.val = val
self.left = left
self.right = right
self.next = next
"""
class Solution:
def connect(self, root: 'Node') -> 'Node':
if not root: return None
queue = [root]
while queue:
size = len(queue)
while size:
cur = queue.pop(0)
cur.next = queue[0] if size > 1 else None
if cur.left: queue.append(cur.left)
if cur.right: queue.append(cur.right)
size -= 1
return root
if not root: return None
mostLeft = root
while mostLeft:
dummyHead = Node(None)
tail = dummyHead
cur = mostLeft
while cur:
if cur.left:
tail.next = cur.left
tail = tail.next
if cur.right:
tail.next = cur.right
tail = tail.next
cur = cur.next
mostLeft = dummyHead.next
return root
总结
先序遍历题目汇总
中序遍历题目汇总
后序遍历题目汇总
层次遍历题目汇总
Reference
Tree-Python(广度优先遍历BFS)(1).
Tree-Python(深度优先遍历DFS)(2).
Tree-Python(深度优先遍历的迭代实现)(3).
算法刷题重温(一):二叉树的 前中后层序 遍历的写法总结(树专题).
|