层序遍历
题目链接/文章讲解/视频讲解:https://programmercarl.com/0102.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E5%B1%82%E5%BA%8F%E9%81%8D%E5%8E%86.html
层序遍历刷题:
- 102.二叉树的层序遍历
- 107.二叉树的层次遍历II
- 199.二叉树的右视图
- 637.二叉树的层平均值
- 429.N叉树的层序遍历
- 515.在每个树行中找最大值
- 116.填充每个节点的下一个右侧节点指针
- 117.填充每个节点的下一个右侧节点指针II
- 104.二叉树的最大深度
- 111.二叉树的最小深度
LeetCode102 二叉树的层序遍历
需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。
而这种层序遍历方式就是图论中的广度优先遍历,只不过我们应用在二叉树上。
使用队列实现二叉树广度优先遍历,动画如下:
❗如何判断同一层的节点:记录队列的长度size,代表二叉树这一层有几个元素
- 6进入队列,size=1,弹出1个元素6
- 将6的左孩子4和右孩子7加入队列,size=2
- 弹出元素4,将4的左右孩子加入
- 弹出元素7,将7的左右孩子加入,size=4(表示第三层有4个节点)
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def levelOrder(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
que = deque()
if not root:
return
res = []
que.append(root)
while que:
length = len(que)
level = []
for i in range(length):
node = que.popleft()
level.append(node.val)
if node.left:
que.append(node.left)
if node.right:
que.append(node.right)
res.append(level)
return res
LeetCode107 二叉树的层次遍历II
✌把res数组反转即可
class Solution(object):
def levelOrderBottom(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
que = deque()
if not root:
return
res = []
que.append(root)
while que:
length = len(que)
level = []
for i in range(length):
node = que.popleft()
level.append(node.val)
if node.left:
que.append(node.left)
if node.right:
que.append(node.right)
res.append(level)
return res[::-1] # 反转
LeetCode199 二叉树的右视图
✌判断是不是每层最后一个元素,如果是则加入res
不是双重列表,所以不需要level=[]
class Solution(object):
def rightSideView(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
que = deque()
if not root:
return
res = []
que.append(root)
while que:
length = len(que)
for i in range(length):
node = que.popleft()
if i == length - 1: # 判断是否是每层最后一个元素
res.append(node.val)
if node.left:
que.append(node.left)
if node.right:
que.append(node.right)
return res
LeetCode637 二叉树的层平均值
✌获得列表后求平均
class Solution(object):
def averageOfLevels(self, root):
"""
:type root: TreeNode
:rtype: List[float]
"""
que = deque()
if not root:
return
res = []
que.append(root)
while que:
length = len(que)
level = []
for i in range(length):
node = que.popleft()
level.append(node.val)
if node.left:
que.append(node.left)
if node.right:
que.append(node.right)
res.append(level)
final_res=[]
for sublist in res:
final_res.append(sum(sublist)/float(len(sublist)))
return final_res
或者直接每层求平均
LeetCode429 N叉树的层序遍历
✌node.children是用list存储
class Solution(object):
def levelOrder(self, root):
"""
:type root: Node
:rtype: List[List[int]]
"""
que = deque()
if not root:
return
res = []
que.append(root)
while que:
length = len(que)
level = []
for i in range(length):
node = que.popleft()
level.append(node.val)
for child in node.children:
que.append(child)
res.append(level)
return res
LeetCode515 在每个树行中找最大值
✌在每一层比较大小
class Solution(object):
def largestValues(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
que = deque()
if not root:
return
res = []
que.append(root)
while que:
max_val = float('-inf')
for i in range(len(que)):
node = que.popleft()
if node.val > max_val:
max_val = node.val
# 或者写成max_val = max(max_val, node.val)
if node.left:
que.append(node.left)
if node.right:
que.append(node.right)
res.append(max_val)
return res
LeetCode116 填充每个节点的下一个右侧节点指针
❗本题依然是层序遍历,只不过在单层遍历的时候记录一下本层的头部节点,然后在遍历的时候让前一个节点指向本节点就可以了
class Solution(object):
def connect(self, root):
"""
:type root: Node
:rtype: Node
"""
que = deque()
if not root:
return
que.append(root)
while que:
length = len(que)
prev = None # 记录前一个节点
for i in range(length):
node = que.popleft()
if prev:
prev.next = node
prev = node
if node.left:
que.append(node.left)
if node.right:
que.append(node.right)
return root
LeetCode117 填充每个节点的下一个右侧节点指针II
同上一题116,这道题目说是二叉树,但116题目说是完整二叉树,其实没有任何差别,一样的代码一样的逻辑
LeetCode104 二叉树的最大深度
✌每层level++
class Solution(object):
def maxDepth(self, root):
"""
:type root: TreeNode
:rtype: int
"""
que = deque()
if not root:
return 0
level = 0
que.append(root)
while que:
length = len(que)
level += 1
for i in range(length):
node = que.popleft()
if node.left:
que.append(node.left)
if node.right:
que.append(node.right)
return level
LeetCode111 二叉树的最小深度
❗只有当左右孩子都为空的时候,才说明遍历的最低点了。如果其中一个孩子为空则不是最低点
class Solution(object):
def minDepth(self, root):
"""
:type root: TreeNode
:rtype: int
"""
que = deque()
if not root:
return 0
depth = 0
que.append(root)
while que:
length = len(que)
depth += 1 # 记录最小深度
for i in range(length):
node = que.popleft()
if not node.left and not node.right: # 当左右孩子都为空的时候,说明是最低点的一层了,退出
return depth
if node.left:
que.append(node.left)
if node.right:
que.append(node.right)
return depth