先看看视频,理解怎么进行层序遍历(层序遍历视频讲解)
理解之后,可以刷一下10道题:
代码展示:
Leetcode102.二叉树的层序遍历
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
# 层序遍历
# 使用队列来实现
queue = []
res = []
if not root: # 当根节点为None时,直接返回空数组
return res
queue.append(root) # 将根节点加入队列
while queue: # 当队列不为空时,遍历二叉树
q_size = len(queue) # 记录此时队列的长度,用来统计每层的节点数量
q_list = [] # 用来记录这一层的节点
while q_size > 0: # 当q_size不为0,说明这一层的节点还未遍历完,还剩q_size个节点
node = queue.pop(0) # 弹出此时队列中的第一个节点
q_list.append(node.val) # 并将这个节点的值加入到一维数组中
q_size -= 1 # 弹出一个节点,本层所剩的节点减1
# 弹出这个节点后,将这个节点的左右子节点加入到队列中,左右子节点为空则不加入
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
# 当q_size为0时,说明一层的节点已经全部遍历完了,将这一层的一维数组添加到res中
res.append(q_list)
return res
LeetCode107.二叉树的层次遍历II
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def levelOrderBottom(self, root: Optional[TreeNode]) -> List[List[int]]:
# 层序遍历
# 自底向上的层序遍历,可以先自上而下进行层序遍历,然后再将数组进行翻转
queue = []
res = []
if not root:
return res # 根节点为空,返回空数组
queue.append(root) # 根节点不为空,将根节点加入队列中
while queue:
q_size = len(queue) # 统计每层的节点数
q_list = []
while q_size > 0:
node = queue.pop(0) # 弹出队列的第一个节点
q_list.append(node.val) # 将弹出的节点的值,加入一维数组中
q_size -= 1 # 本层剩余的节点的数减1
# 将弹出节点的左右子节点加入队列,如果为空则不加入
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
# 当q_size为0时,同一层的节点已经遍历完,将存储同一层节点的一维数组加入res中
res.append(q_list)
# 得到的是自上而下的层序遍历,将数组翻转一下
res = res[::-1]
return res
LeetCode199.二叉树的右视图
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
queue = []
res = []
if not root:
return res # 根节点为空则直接返回空数组
queue.append(root) # 根节点不为空,将根节点加入队列queue
while queue:
q_len = len(queue) # 记录每一层的节点数
# 当每一层剩余节点数不为0时,把每层剩下的节点依次弹出,并把弹出节点的左右子节点加入队列queue
while q_len > 0:
node = queue.pop(0) # 弹出节点
if q_len == 1: # 当每层剩下的节点数为1时,此时这个节点就是右侧能看到的节点
res.append(node.val) # 把这个节点的值添加到res中
q_len -= 1 # 每弹出一个节点,这一层剩下的节点数就减1
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return res
LeetCode637.二叉树的层平均值
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def averageOfLevels(self, root: Optional[TreeNode]) -> List[float]:
# 层序遍历
# 获取到每一层的所有节点的值,然后求平均值
queue = []
res = []
if not root:
return res # 根节点为空,则直接返回空数组
queue.append(root) # 根节点不为空,将根节点加入队列queue
while queue:
q_len, n = len(queue), len(queue) # 获取每层节点的数量
q_sum = 0 # 统计每层节点的值的总和
while q_len > 0:
node = queue.pop(0) # 每层剩余的节点数不为空,弹出队列中的第一个节点
q_sum += node.val # 将每个节点的值进行求和
q_len -= 1 # 弹出一个节点,剩余的节点数减1
# 弹出节点的左右子节点不为空,则将左右子节点加入队列queue
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
# 对每层的节点进行求平均值
avg = q_sum/n
res.append(avg)
return res
LeetCode429.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]]:
res = []
if not root:
return res # 根节点为空,则返回空数组
from collections import deque
queue = deque([root])
while queue:
q_list = []
for _ in range(len(queue)):
node = queue.popleft()
q_list.append(node.val)
# q_len -= 1
if node.children:
queue.extend(node.children)
res.append(q_list)
return res
LeetCode515.在每个树行中找最大值LeetCode515.在每个树行中找最大值
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def largestValues(self, root: Optional[TreeNode]) -> List[int]:
queue = []
res = []
if not root:
return res # 根节点为空,直接返回[]
queue.append(root) # 根节点不为空,将根节点加入到队列queue中
while queue:
q_len = len(queue) # 统计每层的节点数
q_list = [] # 存储每层的节点值
while q_len > 0: # 每层剩余的节点数不为0
node = queue.pop(0) # 从队列中弹出第一个节点
q_list.append(node.val) # 将弹出节点的值,加入到q_list中
q_len -= 1 # 每弹出一个节点,这层剩余的节点数就减1
# 弹出节点的左右子节点不为空,就将左右子节点添加到队列中
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
# 将每层节点值的最大值添加到res中
res.append(max(q_list))
return res
LeetCode116. 填充每个节点的下一个右侧节点指针
"""
# 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: 'Optional[Node]') -> 'Optional[Node]':
queue = []
if not root:
return root # root为空,直接返回
queue.append(root)
while queue:
q_len = len(queue) # 记录每层节点的数量
while q_len:
node = queue.pop(0) # 弹出节点
if q_len == 1: # 若本层剩余的节点为1
node.next = None # 就将弹出的节点的next指向None
else: # 若本层剩余的节点大于1
node.next = queue[0] # 则将弹出的节点的next指向本层下一个弹出的节点
q_len -= 1 # 弹出一个元素,本层所剩节点数减1
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return root
LeetCode117.填充每个节点的下一个右侧节点指针II
"""
# 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':
queue = []
if not root:
return root # root为空,直接返回
queue.append(root)
while queue:
q_len = len(queue) # 记录每层节点的数量
while q_len:
node = queue.pop(0) # 弹出节点
if q_len == 1: # 若本层剩余的节点为1
node.next = None # 就将弹出的节点的next指向None
else: # 若本层剩余的节点大于1
node.next = queue[0] # 则将弹出的节点的next指向本层下一个弹出的节点
q_len -= 1 # 弹出一个元素,本层所剩节点数减1
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return root
LeetCode104.二叉树的最大深度
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
queue = []
s = 0
if not root:
return s # 根节点为空,直接返回0
queue.append(root) # 根节点不为空,将根节点加入到队列queue中
while queue: # 队列queue不为空
q_len = len(queue) # 统计每层的节点数
s += 1 # 层数自加1
while q_len: # 每层剩余的节点数不为0
node = queue.pop(0) # 弹出节点
q_len -= 1 # 弹出节点后,剩余的节点数减1
if node.left: # 弹出节点的左节点不为空,则加入队列
queue.append(node.left)
if node.right: # 弹出节点的右节点不为空,则加入队列
queue.append(node.right)
return s # 当队列为空时,s就是二叉树的最大深度
LeetCode111.二叉树的最小深度
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def minDepth(self, root: Optional[TreeNode]) -> int:
queue = []
s = 0
if not root:
return s
queue.append(root)
while queue:
q_len = len(queue) # 统计每层的节点数
s += 1 # 统计深度
while q_len:
node = queue.pop(0) # 每层剩余节点不为0时,弹出元素
q_len -= 1 # 弹出元素后,剩余节点数减1
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
# 当节点的左右子节点均为空时,就是最小深度
if node.left == None and node.right == None:
return s
给你一棵二叉树的根节点 root
,翻转这棵二叉树,并返回其根节点。
解法一:使用递归(递归视频讲解)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
# 递归法-前序遍历-中左右
# 先处理中间节点,把中间节点的左右子节点进行交换
# 再处理左子树
# 最后处理右子树
def invert(cur):
if cur == None:
return # 当节点为空时,结束本层递归
# 处理当前节点的左右子节点,将左右子节点进行交换
cur.left, cur.right = cur.right, cur.left
invert(cur.left) # 再进行处理节点的左子树
invert(cur.right) # 处理节点的右子树
invert(root)
return root
解法二:使用迭代法
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
# 迭代法
stack = []
cur = root
if not root:
return root
stack.append(root) # 将根节点入栈
while stack:
node = stack.pop() # 将栈中的最后一个节点弹出
# 将节点的左右子节点进行交换
node.left, node.right = node.right, node.left
# 如果节点的左子节点不为空,将左节点入栈
if node.left:
stack.append(node.left)
# 如果节点的右子节点不为空,将右节点入栈
if node.right:
stack.append(node.right)
return root
解法三:使用层序遍历
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
# 层序遍历
queue = []
if not root:
return root
queue.append(root) # 将跟节点入栈
while queue:
q_len = len(queue) # 统计每层的节点数
while q_len > 0: # 每层剩余的节点数不为0时
node = queue.pop(0) # 弹出第一个节点
# 将节点的左右子节点进行交换
node.left, node.right = node.right, node.left
q_len -= 1 # 弹出节点后,每层剩余的节点数减1
# 弹出节点的左节点不为空,将左节点加入栈
if node.left:
queue.append(node.left)
# 弹出节点的右节点不为空,将右节点加入栈
if node.right:
queue.append(node.right)
return root
给你一个二叉树的根节点 root
, 检查它是否轴对称。
使用递归解法(递归视频讲解)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isSymmetric(self, root: Optional[TreeNode]) -> bool:
def symmetric(cur1, cur2):
if cur1 == None and cur2 == None:
return True # 当cur1,cur2都为空
if cur1 == None and cur2 != None:
return False # 当cur1为空,cur2不为空,说明不对称
if cur1 != None and cur2 == None:
return False # 当cur1不为空,cur2为空,说明不对称
if cur1.val != cur2.val:
return False # 当cur1,cur2对应的值不相等,说明不对称
# 当cur1不为空,cur2不为空,cur1,cur2的值相等,则继续比较子节点
# 需要比较cur1的左节点,和cur2的右节点,即对比外侧的节点是否对称
outside = symmetric(cur1.left, cur2.right)
# 比较cur1的右节点,和cur2的左节点,即对比内侧的节点是否对称
inside = symmetric(cur1.right, cur2.left)
# 获取内侧和外侧对比的结果,进行返回
result = outside and inside
return result
# 当根节点不为空,左右节点都为空时,是对称的
if root.left == None and root.right == None:
return True
# 当根节点为空或根节点的左节点或右节点为空时,说明不对称
if not root or root.left == None or root.right == None:
return False
res = symmetric(root.left, root.right)
return res