《代码随想录》学习笔记,原链接:https://programmercarl.com/
1.二叉树基本知识
二叉树的种类
二叉树的存储方式
二叉树的遍历方式
二叉树的定义
2.二叉树的深度优先遍历(递归法、迭代法)
144.二叉树的前序遍历
递归方法
- 递归三部曲
- 核心代码模式
# 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 preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
result = [] # 记录结果
if not root: # 如果当前访问的节点为空,则开始迭代返回
return [] # 这里一定是要返回一个空列表,如果什么都不返回,则会在列表拼接时出错
# 前序遍历:中,左,右
result.append(root.val) # 将中间节点存入到列表中
# 这里不要忘记调用函数前要加self.
result += self.preorderTraversal(root.left) # 迭代访问左子树,并通过“+”将结果列表拼接
result += self.preorderTraversal(root.right) # 迭代访问右子树,并通过“+”将结果列表拼接
# 返回遍历结果
return result
【注】 代码逻辑分析
- ACM模式
# 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 preorderTraversal(self, root):
result = [] # 记录结果
# 递归三部曲:②确定递归的终止条件
if not root: # 如果当前访问的节点为空,则开始迭代返回
return [] # 这里一定是要返回一个空列表,因为preorderTraversal函数的返回值是列表,如果什么都不返回,则会在列表拼接时出错
# 递归三部曲:③确定单层递归的逻辑
# 前序遍历:中,左,右
result.append(root.val) # 将中间节点存入到列表中
# 这里不要忘记调用函数前要加self.
result += self.preorderTraversal(root.left) # 迭代访问左子树,并通过“+”将结果列表拼接
result += self.preorderTraversal(root.right) # 迭代访问右子树,并通过“+”将结果列表拼接
# 返回遍历结果
return result
# 生成二叉树,返回二叉树的根节点
def creat_node(nodes, i):
# 如果当前下标超出范围,或者节点的值为None则返回
if i >= len(nodes) or nodes[i] is None:
return None
root = TreeNode()
root.val = nodes[i]
root.left = creat_node(nodes, i * 2 + 1)
root.right = creat_node(nodes, i * 2 + 2)
# 返回二叉树的根节点
return root
# 输入二叉树节点root
nodes = input("输入节点root:").split(",") # 1,None,2,None,None,3
for i in range(len(nodes)):
if nodes[i] == "None":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
# 根据线性存储列表生成二叉树
root = creat_node(nodes, 0)
# 前序遍历二叉树的节点
solution = Solution()
result = solution.preorderTraversal(root)
print(result)
非递归方法(迭代方法)
- 核心代码模式
# 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 preorderTraversal(self, root: TreeNode) -> List[int]:
if not root: # 如果根节点为None,则返回空列表
return []
result = [] # 创建结果列表
stack = [root] # 创建一个栈,将根节点压入栈
while stack: # 当栈不为空时,进行迭代遍历
node = stack.pop() # 取栈顶元素
result.append(node.val) # 将栈顶元素存入result列表
if node.right:
stack.append(node.right) # 将当前节点的右孩子节点使用append压入栈(栈先入后出,所以先压栈右孩子)
if node.left:
stack.append(node.left) # 将当前节点的左孩子节点使用appen压入栈(栈先入后出,所以先压栈左孩子)
return result # 将遍历结果返回
- ACM模式
# 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 preorderTraversal(self, root):
if not root: # 如果根节点为None,则返回空列表
return []
result = [] # 创建结果列表
stack = [root] # 创建一个栈,将根节点压入栈
while stack: # 当栈不为空时,进行迭代遍历
node = stack.pop() # 取栈顶元素
result.append(node.val) # 将栈顶元素存入result列表
if node.right:
stack.append(node.right) # 将当前节点的右孩子节点使用append压入栈(栈先入后出,所以先压栈右孩子)
if node.left:
stack.append(node.left) # 将当前节点的左孩子节点使用appen压入栈(栈先入后出,所以先压栈左孩子)
return result # 将遍历结果返回
# 生成二叉树,返回二叉树的根节点
def creat_node(nodes, i):
# 如果当前下标超出范围,或者节点的值为None则返回
if i >= len(nodes) or nodes[i] is None:
return None
root = TreeNode()
root.val = nodes[i]
root.left = creat_node(nodes, i * 2 + 1)
root.right = creat_node(nodes, i * 2 + 2)
# 返回二叉树的根节点
return root
# 输入二叉树节点root
nodes = input("输入节点root:").split(",") # 1,None,2,None,None,3
for i in range(len(nodes)):
if nodes[i] == "None":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
# 根据线性存储列表生成二叉树
root = creat_node(nodes, 0)
# 前序遍历二叉树的节点
solution = Solution()
result = solution.preorderTraversal(root)
print(result)
94.二叉树的中序遍历
递归方法
- 核心代码模式
# 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 inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
result = []
if not root:
return []
result += self.inorderTraversal(root.left)
result.append(root.val)
result += self.inorderTraversal(root.right)
return result
- ACM模式
# 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 inorderTraversal(self, root):
result = []
if not root:
return []
result += self.inorderTraversal(root.left)
result.append(root.val)
result += self.inorderTraversal(root.right)
return result
# 生成二叉树,返回二叉树的根节点
def creat_node(nodes, i):
# 如果当前下标超出范围,或者节点的值为None则返回
if i >= len(nodes) or nodes[i] is None:
return None
root = TreeNode()
root.val = nodes[i]
root.left = creat_node(nodes, i * 2 + 1)
root.right = creat_node(nodes, i * 2 + 2)
# 返回二叉树的根节点
return root
# 输入二叉树节点root
nodes = input("输入节点root:").split(",") # 1,None,2,None,None,3
for i in range(len(nodes)):
if nodes[i] == "None":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
# 根据线性存储列表生成二叉树
root = creat_node(nodes, 0)
# 前序遍历二叉树的节点
solution = Solution()
result = solution.inorderTraversal(root)
print(result)
非递归方法(迭代方法)
- 核心代码模式
# 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 inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if not root: # 如果二叉树为空,则直接返回空列表
return []
record = [] # 构建记录栈,注意这里初始化时不能存入节点
result = [] # 构建结果列表
cur = root # 当前访问的节点
while cur or record: # 要遍历的节点和记录栈至少有一个不为空
if cur: # 如果当前节点不为空,则将当前节点存入栈中
record.append(cur) # 注意,这里入栈的是节点,而不单单是节点的取值,为了后续cur回退
cur = cur.left # 访问左孩子节点
else: # 如果当前为空,则回退到栈中的pop节点,并将pop节点的值加入到result中
cur = record.pop() # cur回退
result.append(cur.val) # 将该节点的值加入到result中
cur = cur.right # 访问右孩子节点
return result
- ACM模式
# 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 inorderTraversal(self, root):
if not root: # 如果二叉树为空,则直接返回空列表
return []
record = [] # 构建记录栈,注意这里初始化时不能存入节点
result = [] # 构建结果列表
cur = root # 当前访问的节点
while cur or record: # 要遍历的节点和记录栈至少有一个不为空
if cur: # 如果当前节点不为空,则将当前节点存入栈中
record.append(cur) # 注意,这里入栈的是节点,而不单单是节点的取值,为了后续cur回退
cur = cur.left # 访问左孩子节点
else: # 如果当前为空,则回退到栈中的pop节点,并将pop节点的值加入到result中
cur = record.pop() # cur回退
result.append(cur.val) # 将该节点的值加入到result中
cur = cur.right # 访问右孩子节点
return result
# 前序遍历创建二叉树
def creat_tree(nodes, i):
node = None # 先创建一个空节点
if i < len(nodes) and nodes[i] is not None: # 如果要创建的节点存在且不为None
node = TreeNode(nodes[i]) # 创建该节点
node.left = creat_tree(nodes, i * 2 + 1) # 创建左子节点
node.right = creat_tree(nodes, i * 2 + 2) # 创建右子节点
return node # 返回创建的二叉树的根节点
# 输入节点列表并创建二叉树
nodes = input("输入节点root:").split(",") # 1,null,2,null,null,3
for i in range(len(nodes)):
if nodes[i] == "null":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
root = creat_tree(nodes, 0)
# 二叉树的中序遍历
solution = Solution()
result = solution.inorderTraversal(root)
print(result)
145.二叉树的后序遍历
递归方法
- 核心代码模式
# 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 postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
result = []
if not root:
return []
result += self.postorderTraversal(root.left)
result += self.postorderTraversal(root.right)
result.append(root.val)
return result
- ACM模式
# 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 postorderTraversal(self, root):
result = []
if not root:
return []
result += self.postorderTraversal(root.left)
result += self.postorderTraversal(root.right)
result.append(root.val)
return result
# 生成二叉树,返回二叉树的根节点
def creat_node(nodes, i):
# 如果当前下标超出范围,或者节点的值为None则返回
if i >= len(nodes) or nodes[i] is None:
return None
root = TreeNode()
root.val = nodes[i]
root.left = creat_node(nodes, i * 2 + 1)
root.right = creat_node(nodes, i * 2 + 2)
# 返回二叉树的根节点
return root
# 输入二叉树节点root
nodes = input("输入节点root:").split(",") # 1,None,2,None,None,3
for i in range(len(nodes)):
if nodes[i] == "None":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
# 根据线性存储列表生成二叉树
root = creat_node(nodes, 0)
# 前序遍历二叉树的节点
solution = Solution()
result = solution.postorderTraversal(root)
print(result)
非递归方法(迭代方法)
- 核心代码模式
# 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 postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if not root:
return [] # 注意这里返回的是空列表
result = []
stack = [root]
while stack:
node = stack.pop()
result.append(node.val)
if node.left:
stack.append(node.left)
if node.right:
stack.append(node.right)
return result[::-1]
- ACM模式
# 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 postorderTraversal(self, root):
if not root:
return [] # 注意这里返回的是空列表
result = []
stack = [root]
while stack:
node = stack.pop()
result.append(node.val)
if node.left:
stack.append(node.left)
if node.right:
stack.append(node.right)
return result[::-1]
# 生成二叉树,返回二叉树的根节点
def creat_node(nodes, i):
# 如果当前下标超出范围,或者节点的值为None则返回
if i >= len(nodes) or nodes[i] is None:
return None
root = TreeNode()
root.val = nodes[i]
root.left = creat_node(nodes, i * 2 + 1)
root.right = creat_node(nodes, i * 2 + 2)
# 返回二叉树的根节点
return root
# 输入二叉树节点root
nodes = input("输入节点root:").split(",") # 1,None,2,None,None,3
for i in range(len(nodes)):
if nodes[i] == "None":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
# 根据线性存储列表生成二叉树
root = creat_node(nodes, 0)
# 前序遍历二叉树的节点
solution = Solution()
result = solution.postorderTraversal(root)
print(result)
3.二叉树的广度优先遍历(层序遍历)
102.二叉树的层序遍历
- 核心代码模式
# 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]]:
if not root: # 如果二叉树为空,则直接返回空列表
return []
queue = collections.deque([root]) # 创建队列,用于存放已经访问的二叉树节点(注意,存放的是二叉树节点,不是节点元素值)
result = [] # 存放遍历结果
# 层序遍历
while queue:
lenth = len(queue) # 记录每一层需要弹出的节点数量
record = [] # 存放每一层遍历的结果
for _ in range(lenth): # 弹出队列中的每个节点,并将该节点的左右孩子节点放入队列,注意queue长度会变,这里不能直接使用len(queue)
cur = queue.popleft()
record.append(cur.val) # 弹出当前节点
if cur.left: # 将该节点的左右孩子节点放入队列
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
result.append(record) # 记录这一层的遍历结果
return result
- ACM模式
from collections import deque
# 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):
if not root: # 如果二叉树为空,则直接返回空列表
return []
queue = deque([root]) # 创建队列,用于存放已经访问的二叉树节点(注意,存放的是二叉树节点,不是节点元素值)
result = [] # 存放遍历结果
# 层序遍历
while queue:
lenth = len(queue) # 记录每一层需要弹出的节点数量
record = [] # 存放每一层遍历的结果
for _ in range(lenth): # 弹出队列中的每个节点,并将该节点的左右孩子节点放入队列,注意queue长度会变,这里不能直接使用len(queue)
cur = queue.popleft()
record.append(cur.val) # 弹出当前节点
if cur.left: # 将该节点的左右孩子节点放入队列
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
result.append(record) # 记录这一层的遍历结果
return result
# 前序遍历创建二叉树
def creat_tree(nodes, i):
node = None # 先创建一个空节点
if i < len(nodes) and nodes[i] is not None: # 如果要创建的节点存在且不为None
node = TreeNode(nodes[i]) # 创建该节点
node.left = creat_tree(nodes, i * 2 + 1) # 创建左子节点
node.right = creat_tree(nodes, i * 2 + 2) # 创建右子节点
return node # 返回创建的二叉树的根节点
# 输入节点列表并创建二叉树
nodes = input("输入节点root:").split(",") # 1,null,2,null,null,3
for i in range(len(nodes)):
if nodes[i] == "null":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
root = creat_tree(nodes, 0)
# 二叉树的层序遍历
solution = Solution()
result = solution.levelOrder(root)
print(result)
107.二叉树的层序遍历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]]:
if not root: # 如果二叉树为空,则直接返回空列表
return []
queue = collections.deque([root]) # 构建队列,存放已经访问的节点
result = [] # 构建结果列表
while queue:
lenth = len(queue) # 记录当前层一共有几个节点
record = [] # 记录当前层的元素
for i in range(lenth):
node = queue.popleft()
record.append(node.val) # 获取弹出的节点元素
# 保存当前节点的左、右孩子节点
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
result.append(record) # 将每层的结果保存
return result[::-1] # 倒序输出实现自底向上的层序遍历
- ACM模式
from collections import deque
# 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):
if not root: # 如果二叉树为空,则直接返回空列表
return []
queue = deque([root]) # 构建队列,存放已经访问的节点
result = [] # 构建结果列表
while queue:
lenth = len(queue) # 记录当前层一共有几个节点
record = [] # 记录当前层的元素
for i in range(lenth):
node = queue.popleft()
record.append(node.val) # 获取弹出的节点元素
# 保存当前节点的左、右孩子节点
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
result.append(record) # 将每层的结果保存
return result[::-1] # 倒序输出实现自底向上的层序遍历
# 前序遍历创建二叉树
def creat_tree(nodes, i):
node = None # 先创建一个空节点
if i < len(nodes) and nodes[i] is not None: # 如果要创建的节点存在且不为None
node = TreeNode(nodes[i]) # 创建该节点
node.left = creat_tree(nodes, i * 2 + 1) # 创建左子节点
node.right = creat_tree(nodes, i * 2 + 2) # 创建右子节点
return node # 返回创建的二叉树的根节点
# 输入节点列表并创建二叉树
nodes = input("输入节点root:").split(",") # 3,9,20,null,null,15,7
for i in range(len(nodes)):
if nodes[i] == "null":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
root = creat_tree(nodes, 0)
# 二叉树的层序遍历II
solution = Solution()
result = solution.levelOrderBottom(root)
print(result)
199.二叉树的右视图
- 核心代码模式
# 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]:
if not root: # 如果二叉树为空,则返回空列表
return []
queue = collections.deque([root]) # 创建队列,用于存放已经访问的节点
result = [] # 创建结果列表
while queue: # 只要队列不为空,则继续遍历
record = [] # 用于存放当前层二叉树的节点元素值
lenth = len(queue) # 首先记录当前列表的长度,长度表示当前层二叉树有的节点数量
for _ in range(lenth):
node = queue.popleft()
record.append(node.val) # 取出当前节点,并将元素值存入到record
if node.left:
queue.append(node.left) # 将当前节点的左孩子节点放入队列
if node.right:
queue.append(node.right) # 将当前节点的右孩子节点放入队列
result.append(record[-1]) # 获取每层的最右边节点元素值
return result
- ACM模式
from collections import deque
# 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):
if not root: # 如果二叉树为空,则返回空列表
return []
queue = deque([root]) # 创建队列,用于存放已经访问的节点
result = [] # 创建结果列表
while queue: # 只要队列不为空,则继续遍历
record = [] # 用于存放当前层二叉树的节点元素值
lenth = len(queue) # 首先记录当前列表的长度,长度表示当前层二叉树有的节点数量
for _ in range(lenth):
node = queue.popleft()
record.append(node.val) # 取出当前节点,并将元素值存入到record
if node.left:
queue.append(node.left) # 将当前节点的左孩子节点放入队列
if node.right:
queue.append(node.right) # 将当前节点的右孩子节点放入队列
result.append(record[-1]) # 获取每层的最右边节点元素值
return result
# 前序遍历创建二叉树
def creat_tree(nodes, i):
node = None # 先创建一个空节点
if i < len(nodes) and nodes[i] is not None: # 如果要创建的节点存在且不为None
node = TreeNode(nodes[i]) # 创建该节点
node.left = creat_tree(nodes, i * 2 + 1) # 创建左子节点
node.right = creat_tree(nodes, i * 2 + 2) # 创建右子节点
return node # 返回创建的二叉树的根节点
# 输入节点列表并创建二叉树
nodes = input("输入节点root:").split(",") # 3,9,20,null,null,15,7
for i in range(len(nodes)):
if nodes[i] == "null":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
root = creat_tree(nodes, 0)
# 二叉树的右视图
solution = Solution()
result = solution.rightSideView(root)
print(result)
637.二叉树的层平均值
- 核心代码模式
# 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]:
if not root: # 若二叉树为空,则返回空列表
return []
queue = collections.deque([root]) # 构建层序遍历队列,首先将根节点存入队列
result = []
while queue: # 层序遍历
record = []
lenth = len(queue)
for _ in range(lenth):
node = queue.popleft()
record.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
result.append(sum(record) / len(record)) # 计算每层节点的平均值
return result
- ACM模式
from collections import deque
# 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):
if not root: # 若二叉树为空,则返回空列表
return []
queue = deque([root]) # 构建层序遍历队列,首先将根节点存入队列
result = []
while queue: # 层序遍历
record = []
lenth = len(queue)
for _ in range(lenth):
node = queue.popleft()
record.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
result.append(sum(record) / len(record)) # 计算每层节点的平均值
return result
# 前序遍历创建二叉树
def creat_tree(nodes, i):
node = None # 先创建一个空节点
if i < len(nodes) and nodes[i] is not None: # 如果要创建的节点存在且不为None
node = TreeNode(nodes[i]) # 创建该节点
node.left = creat_tree(nodes, i * 2 + 1) # 创建左子节点
node.right = creat_tree(nodes, i * 2 + 2) # 创建右子节点
return node # 返回创建的二叉树的根节点
# 输入节点列表并创建二叉树
nodes = input("输入节点root:").split(",") # 3,9,20,null,null,15,7
for i in range(len(nodes)):
if nodes[i] == "null":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
root = creat_tree(nodes, 0)
# 二叉树的层平均值
solution = Solution()
result = solution.averageOfLevels(root)
print(result)
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 []
queue = collections.deque([root])
result = []
while queue:
lenth = len(queue)
record = []
for _ in range(lenth):
node = queue.popleft()
record.append(node.val)
for child in node.children: # 遍历每个节点的孩子节点
queue.append(child)
result.append(record) # 生成二维列表
return result
515.在每个树行中找最大值
- 核心代码模式
# 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]:
if not root:
return []
queue = collections.deque([root])
result = []
while queue:
record = []
lenth = len(queue)
for _ in range(lenth):
node = queue.popleft()
record.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
result.append(max(record)) # 获取每层的最大值
return result
- ACM模式
from collections import deque
# 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):
if not root:
return []
queue = deque([root])
result = []
while queue:
record = []
lenth = len(queue)
for _ in range(lenth):
node = queue.popleft()
record.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
result.append(max(record)) # 获取每层的最大值
return result
# 前序遍历创建二叉树
def creat_tree(nodes, i):
node = None # 先创建一个空节点
if i < len(nodes) and nodes[i] is not None: # 如果要创建的节点存在且不为None
node = TreeNode(nodes[i]) # 创建该节点
node.left = creat_tree(nodes, i * 2 + 1) # 创建左子节点
node.right = creat_tree(nodes, i * 2 + 2) # 创建右子节点
return node # 返回创建的二叉树的根节点
# 输入节点列表并创建二叉树
nodes = input("输入节点root:").split(",") # 3,9,20,null,null,15,7
for i in range(len(nodes)):
if nodes[i] == "null":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
root = creat_tree(nodes, 0)
# 在每个树行中找最大值
solution = Solution()
result = solution.largestValues(root)
print(result)
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: 'Optional[Node]') -> 'Optional[Node]':
if not root:
return root
queue = collections.deque([root])
while queue:
lenth = len(queue)
for i in range(lenth):
node = queue.popleft()
if i < lenth - 1: # 将该层的前n - 1个节点指向其右侧节点,最后一个节点由于next默认为空,所以不需要进行操作
node.next = queue[0]
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return root
117.填充每个节点的下一个右侧节点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':
if not root:
return root
queue = collections.deque([root])
while queue:
lenth = len(queue)
for i in range(lenth):
node = queue.popleft()
if i < lenth - 1:
node.next = queue[0] # 将每层的前lenth - 1个节点的next指向右侧节点,最后一个节点由于next默认为None,所以不需要进行操作
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return root
【注】这一题,和116题相比,除了不是完全二叉树(除最底下一层,其余层节点全满,最底下一层节点从左到右连续),代码没有任何区别。
104.二叉树的最大深度
- 核心代码模式
# 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:
if not root:
return 0
queue = collections.deque([root])
result = 1
while queue:
lenth = len(queue)
for _ in range(lenth):
node = queue.popleft()
if not node.left and not node.right and not queue: # 当前节点的左右孩子均为空,并且节点队列为空,说明是最后一层的叶子结点
return result
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
result += 1 # 当前层不是最大深度
return result
- ACM模式
from collections import deque
# 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):
if not root:
return 0
queue = deque([root])
result = 1
while queue:
lenth = len(queue)
for _ in range(lenth):
node = queue.popleft()
if not node.left and not node.right and not queue: # 当前节点的左右孩子均为空,并且节点队列为空,说明是最后一层的叶子结点
return result
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
result += 1 # 当前层不是最大深度
return result
# 前序遍历创建二叉树
def creat_tree(nodes, i):
node = None # 先创建一个空节点
if i < len(nodes) and nodes[i] is not None: # 如果要创建的节点存在且不为None
node = TreeNode(nodes[i]) # 创建该节点
node.left = creat_tree(nodes, i * 2 + 1) # 创建左子节点
node.right = creat_tree(nodes, i * 2 + 2) # 创建右子节点
return node # 返回创建的二叉树的根节点
# 输入节点列表并创建二叉树
nodes = input("输入节点root:").split(",") # 3,9,20,null,null,15,7
for i in range(len(nodes)):
if nodes[i] == "null":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
root = creat_tree(nodes, 0)
# 二叉树的最大深度
solution = Solution()
result = solution.maxDepth(root)
print(result)
111.二叉树的最小深度
- 核心代码模式
# 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:
if not root:
return 0
queue = collections.deque([root])
result = 1 # 记录二叉树深度
while queue:
lenth = len(queue)
for _ in range(lenth):
node = queue.popleft()
if not node.left and not node.right: # 如果当前节点左、右孩子均为空,则为叶子结点
return result
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
result+= 1 # 当前层不存在叶子结点
return result
【注】最大深度和最小深度的区别就在于,最大深度不仅要求某个节点的左、右子节点为空,而且要求队列也为空;而最小深度只需要某个节点的左、右子节点为空 。
- ACM模式
from collections import deque
# 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) -> int:
if not root:
return 0
queue = deque([root])
result = 1 # 记录二叉树深度
while queue:
lenth = len(queue)
for _ in range(lenth):
node = queue.popleft()
if not node.left and not node.right: # 如果当前节点左、右孩子均为空,则为叶子结点
return result
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
result += 1 # 当前层不存在叶子结点
return result
# 前序遍历创建二叉树
def creat_tree(nodes, i):
node = None # 先创建一个空节点
if i < len(nodes) and nodes[i] is not None: # 如果要创建的节点存在且不为None
node = TreeNode(nodes[i]) # 创建该节点
node.left = creat_tree(nodes, i * 2 + 1) # 创建左子节点
node.right = creat_tree(nodes, i * 2 + 2) # 创建右子节点
return node # 返回创建的二叉树的根节点
# 输入节点列表并创建二叉树
nodes = input("输入节点root:").split(",") # 3,9,20,null,null,15,7
for i in range(len(nodes)):
if nodes[i] == "null":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
root = creat_tree(nodes, 0)
# 二叉树的最小深度
solution = Solution()
result = solution.minDepth(root)
print(result)
226.翻转二叉树
深度优先方法
- 核心代码模式
# 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]:
if not root: # 递归终止条件
return None
# 前序遍历进行二叉树翻转
root.left, root.right = root.right, root.left
self.invertTree(root.left) # 递归调用时要加self,而且此处由于不需要节点元素值,所以不需要返回值
self.invertTree(root.right)
return root
- ACM模式
from collections import deque
# 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):
if not root: # 递归终止条件
return None
# 前序遍历进行二叉树翻转
root.left, root.right = root.right, root.left
self.invertTree(root.left) # 递归调用时要加self,而且此处由于不需要节点元素值,所以不需要返回值
self.invertTree(root.right)
return root
# 前序遍历创建二叉树
def levelOrder(root):
if not root: # 如果二叉树为空,则直接返回空列表
return []
queue = deque([root]) # 创建队列,用于存放已经访问的二叉树节点(注意,存放的是二叉树节点,不是节点元素值)
result = [] # 存放遍历结果
# 层序遍历
while queue:
level = [] # 存放每一层遍历的结果
lenth = len(queue) # 记录每一层需要弹出的节点数量
for _ in range(lenth): # 弹出队列中的每个节点,并将该节点的左右孩子节点放入队列,注意queue长度会变,这里不能直接使用len(queue)
cur = queue.popleft()
level.append(cur.val) # 弹出当前节点
if cur.left: # 将该节点的左右孩子节点放入队列
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
result += level # 记录这一层的遍历结果
return result
def creat_tree(nodes, i):
node = None # 先创建一个空节点
if i < len(nodes) and nodes[i] is not None: # 如果要创建的节点存在且不为None
node = TreeNode(nodes[i]) # 创建该节点
node.left = creat_tree(nodes, i * 2 + 1) # 创建左子节点
node.right = creat_tree(nodes, i * 2 + 2) # 创建右子节点
return node # 返回创建的二叉树的根节点
# 输入节点列表并创建二叉树
nodes = input("输入节点root:").split(",") # 4,2,7,1,3,6,9
for i in range(len(nodes)):
if nodes[i] == "null":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
root = creat_tree(nodes, 0)
# 反转二叉树
solution = Solution()
record = solution.invertTree(root)
result = levelOrder(record)
print(result)
广度优先方法
- 核心代码模式
# 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]:
if not root: # 如果二叉树为空,则返回None
return None # 因为最后要的结果是二叉树,而不是二叉树的节点元素值,所以这里不能返回空列表
queue = collections.deque([root])
result = []
# 层序遍历
while queue:
lenth = len(queue)
for _ in range(lenth):
node = queue.popleft()
node.left, node.right = node.right, node.left # 翻转左、右孩子节点
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return root
- ACM模式
from collections import deque
# 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):
if not root: # 如果二叉树为空,则返回None
return None # 因为最后要的结果是二叉树,而不是二叉树的节点元素值,所以这里不能返回空列表
queue = deque([root])
result = []
# 层序遍历
while queue:
lenth = len(queue)
for _ in range(lenth):
node = queue.popleft()
node.left, node.right = node.right, node.left # 翻转左、右孩子节点
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return root
def levelOrder(root):
if not root: # 如果二叉树为空,则直接返回空列表
return []
queue = deque([root]) # 创建队列,用于存放已经访问的二叉树节点(注意,存放的是二叉树节点,不是节点元素值)
result = [] # 存放遍历结果
# 层序遍历
while queue:
level = [] # 存放每一层遍历的结果
lenth = len(queue) # 记录每一层需要弹出的节点数量
for _ in range(lenth): # 弹出队列中的每个节点,并将该节点的左右孩子节点放入队列,注意queue长度会变,这里不能直接使用len(queue)
cur = queue.popleft()
level.append(cur.val) # 弹出当前节点
if cur.left: # 将该节点的左右孩子节点放入队列
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
result += level # 记录这一层的遍历结果
return result
# 前序遍历创建二叉树
def creat_tree(nodes, i):
node = None # 先创建一个空节点
if i < len(nodes) and nodes[i] is not None: # 如果要创建的节点存在且不为None
node = TreeNode(nodes[i]) # 创建该节点
node.left = creat_tree(nodes, i * 2 + 1) # 创建左子节点
node.right = creat_tree(nodes, i * 2 + 2) # 创建右子节点
return node # 返回创建的二叉树的根节点
# 输入节点列表并创建二叉树
nodes = input("输入节点root:").split(",") # 4,2,7,1,3,6,9
for i in range(len(nodes)):
if nodes[i] == "null":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
root = creat_tree(nodes, 0)
# 反转二叉树
solution = Solution()
record = solution.invertTree(root)
result = levelOrder(record)
print(result)
104.二叉树的最大深度
- 核心代码模式
# 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 getHeight(self, root: TreeNode) -> int: # 确定递归函数的参数和返回值
if not root: # 确定递归终止条件
return 0
# 确定每次递归进行的操作
left_height = self.getHeight(root.left)
right_height = self.getHeight(root.right)
result = max(left_height, right_height)
return result + 1
def maxDepth(self, root: Optional[TreeNode]) -> int:
# 调用递归函数,根节点的高度 = 二叉树的深度
result = self.getHeight(root)
return result
- ACM模式
from collections import deque
# 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 getHeight(self, root): # 确定递归函数的参数和返回值
if not root: # 确定递归终止条件
return 0
# 确定每次递归进行的操作
left_height = self.getHeight(root.left)
right_height = self.getHeight(root.right)
result = max(left_height, right_height)
return result + 1
def maxDepth(self, root):
# 调用递归函数,根节点的高度 = 二叉树的深度
result = self.getHeight(root)
return result
# 前序遍历创建二叉树
def creat_tree(nodes, i):
node = None # 先创建一个空节点
if i < len(nodes) and nodes[i] is not None: # 如果要创建的节点存在且不为None
node = TreeNode(nodes[i]) # 创建该节点
node.left = creat_tree(nodes, i * 2 + 1) # 创建左子节点
node.right = creat_tree(nodes, i * 2 + 2) # 创建右子节点
return node # 返回创建的二叉树的根节点
# 输入节点列表并创建二叉树
nodes = input("输入节点root:").split(",") # 4,2,7,1,3,6,9
for i in range(len(nodes)):
if nodes[i] == "null":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
root = creat_tree(nodes, 0)
# 二叉树的最大深度
solution = Solution()
result = solution.maxDepth(root)
print(result)
559.n叉树的最大深度
- 核心代码模式
"""
# Definition for a Node.
class Node:
def __init__(self, val=None, children=None):
self.val = val
self.children = children
"""
class Solution:
def getHeight(self, root: TreeNode) -> int: # 确定递归参数和返回值
# 确定递归终止条件
if not root:
return 0
if not root.children: # 一定要加这个,不然当访问到叶子结点就会停止
return 1
# 确定单次递归的操作
record = []
for child in root.children:
record.append(self.getHeight(child))
result = max(record)
return result + 1
def maxDepth(self, root: 'Node') -> int:
result = self.getHeight(root)
return result
111.二叉树的最小深度
- 核心代码模式
# 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 getHeight(self, root: TreeNode) -> int: # 确定递归的参数和返回值
if not root: # 确定递归终止条件
return 0
# 确定单步递归执行的操作
left_height = self.getHeight(root.left)
right_height = self.getHeight(root.right)
if left_height and not right_height:
return left_height + 1
elif not left_height and right_height:
return right_height + 1
else:
result = min(left_height, right_height)
return result + 1
def minDepth(self, root: Optional[TreeNode]) -> int:
result = self.getHeight(root)
return result
- ACM模式
from collections import deque
# 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 getHeight(self, root): # 确定递归的参数和返回值
if not root: # 确定递归终止条件
return 0
# 确定单步递归执行的操作
left_height = self.getHeight(root.left)
right_height = self.getHeight(root.right)
if left_height and not right_height:
return left_height + 1
elif not left_height and right_height:
return right_height + 1
else:
result = min(left_height, right_height)
return result + 1
def minDepth(self, root):
result = self.getHeight(root)
return result
# 前序遍历创建二叉树
def creat_tree(nodes, i):
node = None # 先创建一个空节点
if i < len(nodes) and nodes[i] is not None: # 如果要创建的节点存在且不为None
node = TreeNode(nodes[i]) # 创建该节点
node.left = creat_tree(nodes, i * 2 + 1) # 创建左子节点
node.right = creat_tree(nodes, i * 2 + 2) # 创建右子节点
return node # 返回创建的二叉树的根节点
# 输入节点列表并创建二叉树
nodes = input("输入节点root:").split(",") # 4,2,7,1,3,6,9
for i in range(len(nodes)):
if nodes[i] == "null":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
root = creat_tree(nodes, 0)
# 二叉树的最小深度
solution = Solution()
result = solution.minDepth(root)
print(result)
222.完全二叉树的节点个数
- 核心代码模式
# 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 getNum(self, root: TreeNode) -> int: # 确定递归参数和返回值
# 确定递归终止条件
if not root:
return 0
# 确定递归终止条件(找到满二叉子树)
left_node, right_node = root.left, root.right
left_depth, right_depth = 0, 0
while left_node:
left_depth += 1
left_node = left_node.left
while right_node:
right_depth += 1
right_node = right_node.right
if left_depth == right_depth:
return 2 ** (left_depth + 1) - 1 # 根据满二叉子树的深度,确定整个子树的节点数
# 单次递归操作(后序可以让中心节点找两边子树要信息)
left_num = self.getNum(root.left)
right_num = self.getNum(root.right)
result = left_num + right_num + 1
return result
def countNodes(self, root: Optional[TreeNode]) -> int:
result = self.getNum(root)
return result
- ACM模式
from collections import deque
# 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 getNum(self, root: TreeNode) -> int: # 确定递归参数和返回值
# 确定递归终止条件
if not root:
return 0
# 确定递归终止条件(找到满二叉子树)
left_node, right_node = root.left, root.right
left_depth, right_depth = 0, 0
while left_node:
left_depth += 1
left_node = left_node.left
while right_node:
right_depth += 1
right_node = right_node.right
if left_depth == right_depth:
return 2 ** (left_depth + 1) - 1 # 根据满二叉子树的深度,确定整个子树的节点数
# 单次递归操作(后序可以让中心节点找两边子树要信息)
left_num = self.getNum(root.left)
right_num = self.getNum(root.right)
result = left_num + right_num + 1
return result
def countNodes(self, root):
result = self.getNum(root)
return result
# 前序遍历创建二叉树
def creat_tree(nodes, i):
node = None # 先创建一个空节点
if i < len(nodes) and nodes[i] is not None: # 如果要创建的节点存在且不为None
node = TreeNode(nodes[i]) # 创建该节点
node.left = creat_tree(nodes, i * 2 + 1) # 创建左子节点
node.right = creat_tree(nodes, i * 2 + 2) # 创建右子节点
return node # 返回创建的二叉树的根节点
# 输入节点列表并创建二叉树
nodes = input("输入节点root:").split(",") # 4,2,7,1,3,6,9
for i in range(len(nodes)):
if nodes[i] == "null":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
root = creat_tree(nodes, 0)
# 完全二叉树的节点个数
solution = Solution()
result = solution.countNodes(root)
print(result)
110.平衡二叉树
- 核心代码模式
# 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 getHeight(self, root: TreeNode) -> int: # 确定递归参数和返回值
# 确定递归终止条件
if not root:
return 0
# 确定单步递归操作,设置非平衡二叉树的标志为height = -1
left_height = self.getHeight(root.left) # 获取当前节点左子树的高度
if left_height == -1:
return -1
right_height = self.getHeight(root.right) # 获取当前节点右子树的高度
if right_height == -1:
return -1
height_deffer = abs(left_height - right_height) # 获取当前节点左右子树的高度差
# 若高度差大于1,则该树为非平衡,直接返回标识-1,否则返回当前子树的高度,用于上一层进行高度差比较
if height_deffer > 1:
return -1
else:
return max(left_height, right_height) + 1
def isBalanced(self, root: Optional[TreeNode]) -> bool:
height = self.getHeight(root) # 返回值为整个二叉树的高度,或者非平衡标识-1
return height != -1
- ACM模式
from collections import deque
# 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 getHeight(self, root): # 确定递归参数和返回值
# 确定递归终止条件
if not root:
return 0
# 确定单步递归操作,设置非平衡二叉树的标志为height = -1
left_height = self.getHeight(root.left) # 获取当前节点左子树的高度
if left_height == -1:
return -1
right_height = self.getHeight(root.right) # 获取当前节点右子树的高度
if right_height == -1:
return -1
height_deffer = abs(left_height - right_height) # 获取当前节点左右子树的高度差
# 若高度差大于1,则该树为非平衡,直接返回标识-1,否则返回当前子树的高度,用于上一层进行高度差比较
if height_deffer > 1:
return -1
else:
return max(left_height, right_height) + 1
def isBalanced(self, root):
height = self.getHeight(root) # 返回值为整个二叉树的高度,或者非平衡标识-1
return height != -1
# 前序遍历创建二叉树
def creat_tree(nodes, i):
node = None # 先创建一个空节点
if i < len(nodes) and nodes[i] is not None: # 如果要创建的节点存在且不为None
node = TreeNode(nodes[i]) # 创建该节点
node.left = creat_tree(nodes, i * 2 + 1) # 创建左子节点
node.right = creat_tree(nodes, i * 2 + 2) # 创建右子节点
return node # 返回创建的二叉树的根节点
# 输入节点列表并创建二叉树
nodes = input("输入节点root:").split(",") # 4,2,7,1,3,6,9
for i in range(len(nodes)):
if nodes[i] == "null":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
root = creat_tree(nodes, 0)
# 平衡二叉树
solution = Solution()
result = solution.isBalanced(root)
print(result)
257.二叉树的所有路径
- 核心代码模式
# 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 get_path(self, root, path: List[str], result: List[str]): # 确定递归参数和返回值
path.append(root.val) # 向路径中加入当前节点
# 确定递归终止条件
if not root.left and not root.right:
path_str = '->'.join(map(str, path)) # 保存当前路径
result.append(path_str)
return
# 确定单步递归操作
if root.left:
self.get_path(root.left, path, result)
path.pop() # 回溯
if root.right:
self.get_path(root.right, path, result)
path.pop() # 回溯
def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
path, self.result = [], []
self.get_path(root, path, self.result)
return self.result
- ACM模式
from collections import deque
# 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 get_path(self, root, path, result): # 确定递归参数和返回值
path.append(root.val) # 向路径中加入当前节点
# 确定递归终止条件
if not root.left and not root.right:
path_str = '->'.join(map(str, path)) # 保存当前路径
result.append(path_str)
return
# 确定单步递归操作
if root.left:
self.get_path(root.left, path, result)
path.pop() # 回溯
if root.right:
self.get_path(root.right, path, result)
path.pop() # 回溯
def binaryTreePaths(self, root):
path, self.result = [], []
self.get_path(root, path, self.result)
return self.result
# 前序遍历创建二叉树
def creat_tree(nodes, i):
node = None # 先创建一个空节点
if i < len(nodes) and nodes[i] is not None: # 如果要创建的节点存在且不为None
node = TreeNode(nodes[i]) # 创建该节点
node.left = creat_tree(nodes, i * 2 + 1) # 创建左子节点
node.right = creat_tree(nodes, i * 2 + 2) # 创建右子节点
return node # 返回创建的二叉树的根节点
# 输入节点列表并创建二叉树
nodes = input("输入节点root:").split(",") # 4,2,7,1,3,6,9
for i in range(len(nodes)):
if nodes[i] == "null":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
root = creat_tree(nodes, 0)
# 二叉树的所有路径
solution = Solution()
result = solution.binaryTreePaths(root)
print(result)
404.左叶子之和
- 核心代码模式
# 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 getNum(self, node: TreeNode, is_left: bool) -> int: # 确定递归参数和返回值
# 确定递归终止条件
if not node:
return 0
if not node.left and not node.right and is_left:
return node.val
# 确定单次递归操作
left_num = self.getNum(node.left, True)
right_num = self.getNum(node.right, False)
result = left_num + right_num
return result
def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
result = self.getNum(root, False)
return result
- ACM模式
from collections import deque
# 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 getNum(self, node, is_left): # 确定递归参数和返回值
# 确定递归终止条件
if not node:
return 0
if not node.left and not node.right and is_left:
return node.val
# 确定单次递归操作
left_num = self.getNum(node.left, True)
right_num = self.getNum(node.right, False)
result = left_num + right_num
return result
def sumOfLeftLeaves(self, root):
result = self.getNum(root, False)
return result
# 前序遍历创建二叉树
def creat_tree(nodes, i):
node = None # 先创建一个空节点
if i < len(nodes) and nodes[i] is not None: # 如果要创建的节点存在且不为None
node = TreeNode(nodes[i]) # 创建该节点
node.left = creat_tree(nodes, i * 2 + 1) # 创建左子节点
node.right = creat_tree(nodes, i * 2 + 2) # 创建右子节点
return node # 返回创建的二叉树的根节点
# 输入节点列表并创建二叉树
nodes = input("输入节点root:").split(",") # 4,2,7,1,3,6,9
for i in range(len(nodes)):
if nodes[i] == "null":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
root = creat_tree(nodes, 0)
# 左叶子之和
solution = Solution()
result = solution.sumOfLeftLeaves(root)
print(result)
513.找树左下角的值
- 核心代码模式
# 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 findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
queue = collections.deque([root]) # 构建层序遍历队列
# 层序遍历
while queue:
lenth = len(queue)
record = []
for _ in range(lenth):
node = queue.popleft()
record.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
result = record[0]
return result
- ACM模式
from collections import deque
# 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 findBottomLeftValue(self, root):
queue = deque([root]) # 构建层序遍历队列
# 层序遍历
while queue:
lenth = len(queue)
record = []
for _ in range(lenth):
node = queue.popleft()
record.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
result = record[0]
return result
# 前序遍历创建二叉树
def creat_tree(nodes, i):
node = None # 先创建一个空节点
if i < len(nodes) and nodes[i] is not None: # 如果要创建的节点存在且不为None
node = TreeNode(nodes[i]) # 创建该节点
node.left = creat_tree(nodes, i * 2 + 1) # 创建左子节点
node.right = creat_tree(nodes, i * 2 + 2) # 创建右子节点
return node # 返回创建的二叉树的根节点
# 输入节点列表并创建二叉树
nodes = input("输入节点root:").split(",") # 4,2,7,1,3,6,9
for i in range(len(nodes)):
if nodes[i] == "null":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
root = creat_tree(nodes, 0)
# 左叶子之和
solution = Solution()
result = solution.findBottomLeftValue(root)
print(result)
112.路径总和
- 核心代码模式
# 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 getPath(self, node: TreeNode, count: int) -> bool: # 确定递归参数和返回值
# 确定递归终止条件
if not node.left and not node.right and count == 0:
return True
if not node.left and not node.right and count != 0: # 这里不能是else
return False
# 确定单次递归操作
if node.left:
count -= node.left.val # 进入递归之前减
if self.getPath(node.left, count):
return True
count += node.left.val
if node.right:
count -= node.right.val # 进入递归之前减
if self.getPath(node.right, count):
return True
count += node.right.val
return False
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
if not root:
return False
result = self.getPath(root, targetSum - root.val) # 进入递归之前减
return result
- ACM模式
from collections import deque
# 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 getPath(self, node: TreeNode, count: int) -> bool: # 确定递归参数和返回值
# 确定递归终止条件
if not node.left and not node.right and count == 0:
return True
if not node.left and not node.right and count != 0: # 这里不能是else
return False
# 确定单次递归操作
if node.left:
count -= node.left.val # 进入递归之前减
if self.getPath(node.left, count):
return True
count += node.left.val
if node.right:
count -= node.right.val # 进入递归之前减
if self.getPath(node.right, count):
return True
count += node.right.val
return False
def hasPathSum(self, root, targetSum):
if not root:
return False
result = self.getPath(root, targetSum - root.val) # 进入递归之前减
return result
# 前序遍历创建二叉树
def creat_tree(nodes, i):
node = None # 先创建一个空节点
if i < len(nodes) and nodes[i] is not None: # 如果要创建的节点存在且不为None
node = TreeNode(nodes[i]) # 创建该节点
node.left = creat_tree(nodes, i * 2 + 1) # 创建左子节点
node.right = creat_tree(nodes, i * 2 + 2) # 创建右子节点
return node # 返回创建的二叉树的根节点
# 输入节点列表并创建二叉树
nodes = input("输入节点root:").split(",") # 4,2,7,1,3,6,9
targetSum = int(input("输入目标值targetSum:"))
for i in range(len(nodes)):
if nodes[i] == "null":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
root = creat_tree(nodes, 0)
# 左叶子之和
solution = Solution()
result = solution.hasPathSum(root, targetSum)
print(result)
113.路径总和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 __init__(self):
self.result = []
self.record = []
def getPath(self, node: TreeNode, count: int) -> List[List[int]]:
# 确定递归终止条件
if not node.left and not node.right and count == 0:
self.result.append(self.record[:]) # 注意这里一定是append(self.record[:]),不然只会加进record的第一个元素
return
if not node.left and not node.right and count != 0: # 这里不能是else
return
# 确定单次递归操作
if node.left:
count -= node.left.val # 进入递归前减
self.record.append(node.left.val)
self.getPath(node.left, count)
self.record.pop()
count += node.left.val
if node.right:
count -= node.right.val # 进入递归前减
self.record.append(node.right.val)
self.getPath(node.right, count)
self.record.pop()
count += node.right.val
return
def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
if not root:
return []
self.record.append(root.val)
self.getPath(root, targetSum - root.val) # 进入递归前减
return self.result
- ACM模式
from collections import deque
# 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 __init__(self):
self.result = []
self.record = []
def getPath(self, node, count):
# 确定递归终止条件
if not node.left and not node.right and count == 0:
self.result.append(self.record[:]) # 注意这里一定是append(self.record[:]),不然只会加进record的第一个元素
return
if not node.left and not node.right and count != 0: # 这里不能是else
return
# 确定单次递归操作
if node.left:
count -= node.left.val # 进入递归前减
self.record.append(node.left.val)
self.getPath(node.left, count)
self.record.pop()
count += node.left.val
if node.right:
count -= node.right.val # 进入递归前减
self.record.append(node.right.val)
self.getPath(node.right, count)
self.record.pop()
count += node.right.val
return
def pathSum(self, root, targetSum):
if not root:
return []
self.record.append(root.val)
self.getPath(root, targetSum - root.val) # 进入递归前减
return self.result
# 前序遍历创建二叉树
def creat_tree(nodes, i):
node = None # 先创建一个空节点
if i < len(nodes) and nodes[i] is not None: # 如果要创建的节点存在且不为None
node = TreeNode(nodes[i]) # 创建该节点
node.left = creat_tree(nodes, i * 2 + 1) # 创建左子节点
node.right = creat_tree(nodes, i * 2 + 2) # 创建右子节点
return node # 返回创建的二叉树的根节点
# 输入节点列表并创建二叉树
nodes = input("输入节点root:").split(",") # 4,2,7,1,3,6,9
targetSum = int(input("输入目标值targetSum:"))
for i in range(len(nodes)):
if nodes[i] == "null":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
root = creat_tree(nodes, 0)
# 左叶子之和
solution = Solution()
result = solution.pathSum(root, targetSum)
print(result)
106.从中序与后序遍历序列构造二叉树
- 核心代码模式
# 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 getTree(self, inorder: List[int], postorder: List[int]) -> TreeNode: # 确定递归参数和返回值
# 确定递归终止条件
if len(postorder) == 0:
return None
root = TreeNode(val=postorder[-1]) # 后序数组的最后一个元素为中节点元素
# 寻找中节点元素值对应的中序数组位置,作为切割点
index = inorder.index(root.val)
# 切割中序、后序数组,均采用左闭右开
in_left, in_right = inorder[:index], inorder[index + 1:]
post_left, post_right = postorder[:index], postorder[index:-1]
# 递归处理左、右区间
root.left = self.getTree(in_left, post_left)
root.right = self.getTree(in_right, post_right)
return root
def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:
result = self.getTree(inorder, postorder)
return result
- ACM模式
from collections import deque
# 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 getTree(self, inorder, postorder) -> TreeNode: # 确定递归参数和返回值
# 确定递归终止条件
if len(postorder) == 0:
return None
root = TreeNode(val=postorder[-1]) # 后序数组的最后一个元素为中节点元素
# 寻找中节点元素值对应的中序数组位置,作为切割点
index = inorder.index(root.val)
# 切割中序、后序数组,均采用左闭右开
in_left, in_right = inorder[:index], inorder[index + 1:]
post_left, post_right = postorder[:index], postorder[index:-1]
# 递归处理左、右区间
root.left = self.getTree(in_left, post_left)
root.right = self.getTree(in_right, post_right)
return root
def buildTree(self, inorder, postorder):
result = self.getTree(inorder, postorder)
return result
def levelOrder(root):
if not root: # 如果二叉树为空,则直接返回空列表
return []
queue = deque([root]) # 创建队列,用于存放已经访问的二叉树节点(注意,存放的是二叉树节点,不是节点元素值)
result = [] # 存放遍历结果
# 层序遍历
while queue:
level = [] # 存放每一层遍历的结果
lenth = len(queue) # 记录每一层需要弹出的节点数量
for _ in range(lenth): # 弹出队列中的每个节点,并将该节点的左右孩子节点放入队列,注意queue长度会变,这里不能直接使用len(queue)
cur = queue.popleft()
level.append(cur.val) # 弹出当前节点
if cur.left: # 将该节点的左右孩子节点放入队列
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
result += level # 记录这一层的遍历结果
return result
# 输入节点列表并创建二叉树
inorder = list(map(int, input("输入中序数组inorder:").split(","))) # 9,3,15,20,7
postorder = list(map(int, input("输入后序数组postorder:").split(","))) # 9,15,7,20,3
# 从中序与后序遍历序列构造二叉树
solution = Solution()
result = solution.buildTree(inorder, postorder)
result = levelOrder(result)
print(result)
105.从前序与中序遍历序列构造二叉树
- 核心代码模式
# 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 getTree(self, preorder: List[int], inorder: List[int]) -> TreeNode: # 确定递归参数和返回值
# 确定递归终止条件
if len(preorder) == 0:
return None
# 前序数组的第一个元素为中节点元素
root = TreeNode(preorder[0])
# 寻找中节点元素对应的中序数组位置,作为切割点
index = inorder.index(root.val)
# 切割前、中序数组,均采用左闭右开
in_left, in_right = inorder[:index], inorder[index + 1:]
pre_left, pre_right = preorder[1:index + 1], preorder[index + 1:]
# 递归处理左、右区间
root.left = self.getTree(pre_left, in_left)
root.right = self.getTree(pre_right, in_right)
return root
def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
result = self.getTree(preorder, inorder)
return result
- ACM模式
from collections import deque
# 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 getTree(self, preorder, inorder): # 确定递归参数和返回值
# 确定递归终止条件
if len(preorder) == 0:
return None
# 前序数组的第一个元素为中节点元素
root = TreeNode(preorder[0])
# 寻找中节点元素对应的中序数组位置,作为切割点
index = inorder.index(root.val)
# 切割前、中序数组,均采用左闭右开
in_left, in_right = inorder[:index], inorder[index + 1:]
pre_left, pre_right = preorder[1:index + 1], preorder[index + 1:]
# 递归处理左、右区间
root.left = self.getTree(pre_left, in_left)
root.right = self.getTree(pre_right, in_right)
return root
def buildTree(self, preorder, inorder):
result = self.getTree(preorder, inorder)
return result
def levelOrder(root):
if not root: # 如果二叉树为空,则直接返回空列表
return []
queue = deque([root]) # 创建队列,用于存放已经访问的二叉树节点(注意,存放的是二叉树节点,不是节点元素值)
result = [] # 存放遍历结果
# 层序遍历
while queue:
level = [] # 存放每一层遍历的结果
lenth = len(queue) # 记录每一层需要弹出的节点数量
for _ in range(lenth): # 弹出队列中的每个节点,并将该节点的左右孩子节点放入队列,注意queue长度会变,这里不能直接使用len(queue)
cur = queue.popleft()
level.append(cur.val) # 弹出当前节点
if cur.left: # 将该节点的左右孩子节点放入队列
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
result += level # 记录这一层的遍历结果
return result
# 输入节点列表并创建二叉树
preorder = list(map(int, input("输入前序数组preorder:").split(","))) # 3,9,20,15,7
inorder = list(map(int, input("输入中序数组inorder:").split(","))) # 9,3,15,20,7
# 从前序和中序遍历序列构造二叉树
solution = Solution()
result = solution.buildTree(preorder, inorder)
result = levelOrder(result)
print(result)
654.最大二叉树
- 核心代码模式
# 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 getTree(self, nums: List[int]) -> TreeNode: # 确定递归参数和返回值
# 确定递归终止条件
if len(nums) == 0:
return None
# 找到nums中的最大值和下标,构造根节点
root = TreeNode(max(nums))
index = nums.index(root.val)
# 根据最大值位置,切分nums,均按照左闭右开
left_nums = nums[:index]
right_nums = nums[index + 1:]
# 递归处理左、右区间,构造左、右子树
root.left = self.getTree(left_nums)
root.right = self.getTree(right_nums)
return root
def constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
result = self.getTree(nums) # 构造二叉树的题目,一定要用前序遍历
return result
- ACM模式
from collections import deque
# 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 getTree(self, nums): # 确定递归参数和返回值
# 确定递归终止条件
if len(nums) == 0:
return None
# 找到nums中的最大值和下标,构造根节点
root = TreeNode(max(nums))
index = nums.index(root.val)
# 根据最大值位置,切分nums,均按照左闭右开
left_nums = nums[:index]
right_nums = nums[index + 1:]
# 递归处理左、右区间,构造左、右子树
root.left = self.getTree(left_nums)
root.right = self.getTree(right_nums)
return root
def constructMaximumBinaryTree(self, nums):
result = self.getTree(nums) # 构造二叉树的题目,一定要用前序遍历
return result
def levelOrder(root):
if not root: # 如果二叉树为空,则直接返回空列表
return []
queue = deque([root]) # 创建队列,用于存放已经访问的二叉树节点(注意,存放的是二叉树节点,不是节点元素值)
result = [] # 存放遍历结果
# 层序遍历
while queue:
level = [] # 存放每一层遍历的结果
lenth = len(queue) # 记录每一层需要弹出的节点数量
for _ in range(lenth): # 弹出队列中的每个节点,并将该节点的左右孩子节点放入队列,注意queue长度会变,这里不能直接使用len(queue)
cur = queue.popleft()
level.append(cur.val) # 弹出当前节点
if cur.left: # 将该节点的左右孩子节点放入队列
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
result += level # 记录这一层的遍历结果
return result
# 输入节点列表并创建二叉树
root = list(map(int, input("输入节点数组root:").split(","))) # 3,2,1,6,0,5
# 从中序与后序遍历序列构造二叉树
solution = Solution()
result = solution.constructMaximumBinaryTree(root)
result = levelOrder(result)
print(result)
617.合并二叉树
- 核心代码模式
# 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 getTree(self, root1: TreeNode, root2: TreeNode) -> TreeNode: # 确定递归参数和返回值
# 确定递归终止条件
if not root1:
return root2
if not root2:
return root1
# 确定单次递归操作
root1.val += root2.val
root1.left = self.getTree(root1.left, root2.left)
root1.right = self.getTree(root1.right, root2.right)
return root1
def mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
result = self.getTree(root1, root2)
return result
- ACM模式
from collections import deque
# 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 getTree(self, root1: TreeNode, root2: TreeNode) -> TreeNode: # 确定递归参数和返回值
# 确定递归终止条件
if not root1:
return root2
if not root2:
return root1
# 确定单次递归操作
root1.val += root2.val
root1.left = self.getTree(root1.left, root2.left)
root1.right = self.getTree(root1.right, root2.right)
return root1
def mergeTrees(self, root1, root2):
result = self.getTree(root1, root2)
return result
def levelOrder(root):
if not root: # 如果二叉树为空,则直接返回空列表
return []
queue = deque([root]) # 创建队列,用于存放已经访问的二叉树节点(注意,存放的是二叉树节点,不是节点元素值)
result = [] # 存放遍历结果
# 层序遍历
while queue:
level = [] # 存放每一层遍历的结果
lenth = len(queue) # 记录每一层需要弹出的节点数量
for _ in range(lenth): # 弹出队列中的每个节点,并将该节点的左右孩子节点放入队列,注意queue长度会变,这里不能直接使用len(queue)
cur = queue.popleft()
level.append(cur.val) # 弹出当前节点
if cur.left: # 将该节点的左右孩子节点放入队列
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
result += level # 记录这一层的遍历结果
return result
def creat_tree(nodes, i):
node = None # 先创建一个空节点
if i < len(nodes) and nodes[i] is not None: # 如果要创建的节点存在且不为None
node = TreeNode(nodes[i]) # 创建该节点
node.left = creat_tree(nodes, i * 2 + 1) # 创建左子节点
node.right = creat_tree(nodes, i * 2 + 2) # 创建右子节点
return node # 返回创建的二叉树的根节点
# 输入节点列表并创建二叉树
nodes1 = input("输入节点root1:").split(",") # 1,3,2,5
for i in range(len(nodes1)):
if nodes1[i] == "null":
nodes1[i] = None
else:
nodes1[i] = int(nodes1[i])
root1 = creat_tree(nodes1, 0)
nodes2 = input("输入节点root2:").split(",") # 2,1,3,null,4,null,7
for i in range(len(nodes2)):
if nodes2[i] == "null":
nodes2[i] = None
else:
nodes2[i] = int(nodes2[i])
root2 = creat_tree(nodes2, 0)
# 合并二叉树
solution = Solution()
result = solution.mergeTrees(root1, root2)
result = levelOrder(result)
print(result)
700.二叉搜索树中的搜索
- 核心代码模式
# 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 searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
if not root:
return None
while root:
if val < root.val:
root = root.left
elif val > root.val:
root = root.right
else:
return root
return None
- ACM模式
from collections import deque
# 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 searchBST(self, root, val):
if not root:
return None
while root:
if val < root.val:
root = root.left
elif val > root.val:
root = root.right
else:
return root
return None
def levelOrder(root):
if not root: # 如果二叉树为空,则直接返回空列表
return []
queue = deque([root]) # 创建队列,用于存放已经访问的二叉树节点(注意,存放的是二叉树节点,不是节点元素值)
result = [] # 存放遍历结果
# 层序遍历
while queue:
level = [] # 存放每一层遍历的结果
lenth = len(queue) # 记录每一层需要弹出的节点数量
for _ in range(lenth): # 弹出队列中的每个节点,并将该节点的左右孩子节点放入队列,注意queue长度会变,这里不能直接使用len(queue)
cur = queue.popleft()
level.append(cur.val) # 弹出当前节点
if cur.left: # 将该节点的左右孩子节点放入队列
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
result += level # 记录这一层的遍历结果
return result
def creat_tree(nodes, i):
node = None # 先创建一个空节点
if i < len(nodes) and nodes[i] is not None: # 如果要创建的节点存在且不为None
node = TreeNode(nodes[i]) # 创建该节点
node.left = creat_tree(nodes, i * 2 + 1) # 创建左子节点
node.right = creat_tree(nodes, i * 2 + 2) # 创建右子节点
return node # 返回创建的二叉树的根节点
# 输入节点列表并创建二叉树
nodes = input("输入节点root:").split(",") # 4,2,7,1,3
for i in range(len(nodes)):
if nodes[i] == "null":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
root = creat_tree(nodes, 0)
val = int(input("输入整数值val:"))
# 二叉搜索树中的搜索
solution = Solution()
result = solution.searchBST(root, val)
result = levelOrder(result)
print(result)
98.验证二叉搜索树
- 核心代码模式
# 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 __init__(self): # 设置对比值
self.max_value = float('-inf')
def getTree(self, root: TreeNode) -> bool: # 确定递归参数和返回值
# 确定递归终止条件
if not root:
return True
# 确定单次递归操作(中序遍历)
left_node = self.getTree(root.left)
if root.val > self.max_value:
self.max_value = root.val
else:
return False
right_node = self.getTree(root.right)
return left_node and right_node
def isValidBST(self, root: Optional[TreeNode]) -> bool:
result = self.getTree(root)
return result
- ACM模式
from collections import deque
# 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 __init__(self): # 设置对比值
self.max_value = float('-inf')
def getTree(self, root: TreeNode) -> bool: # 确定递归参数和返回值
# 确定递归终止条件
if not root:
return True
# 确定单次递归操作(中序遍历)
left_node = self.getTree(root.left)
if root.val > self.max_value:
self.max_value = root.val
else:
return False
right_node = self.getTree(root.right)
return left_node and right_node
def isValidBST(self, root):
result = self.getTree(root)
return result
def creat_tree(nodes, i):
node = None # 先创建一个空节点
if i < len(nodes) and nodes[i] is not None: # 如果要创建的节点存在且不为None
node = TreeNode(nodes[i]) # 创建该节点
node.left = creat_tree(nodes, i * 2 + 1) # 创建左子节点
node.right = creat_tree(nodes, i * 2 + 2) # 创建右子节点
return node # 返回创建的二叉树的根节点
# 输入节点列表并创建二叉树
nodes = input("输入节点root:").split(",") # 4,2,7,1,3
for i in range(len(nodes)):
if nodes[i] == "null":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
root = creat_tree(nodes, 0)
# val = int(input("输入整数值val:"))
# 验证二叉搜索树
solution = Solution()
result = solution.isValidBST(root)
print(result)
530.二叉搜索树的最小绝对差
- 核心代码模式
# 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 __init__(self):
self.pre_val = None
self.min_diff = float('inf')
def getTree(self, root: TreeNode) -> int: # 确定递归参数和返回值
# 确定递归终止条件
if not root:
return
# 确定单次递归操作
self.getTree(root.left)
if self.pre_val is not None:
self.min_diff = min(abs(root.val - self.pre_val), self.min_diff)
self.pre_val = root.val
self.getTree(root.right)
return self.min_diff
def getMinimumDifference(self, root: Optional[TreeNode]) -> int:
result = self.getTree(root)
return result
- ACM模式
from collections import deque
# 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 __init__(self):
self.pre_val = None
self.min_diff = float('inf')
def getTree(self, root: TreeNode) -> int: # 确定递归参数和返回值
# 确定递归终止条件
if not root:
return
# 确定单次递归操作
self.getTree(root.left)
if self.pre_val is not None:
self.min_diff = min(abs(root.val - self.pre_val), self.min_diff)
self.pre_val = root.val
self.getTree(root.right)
return self.min_diff
def getMinimumDifference(self, root) -> int:
result = self.getTree(root)
return result
def creat_tree(nodes, i):
node = None # 先创建一个空节点
if i < len(nodes) and nodes[i] is not None: # 如果要创建的节点存在且不为None
node = TreeNode(nodes[i]) # 创建该节点
node.left = creat_tree(nodes, i * 2 + 1) # 创建左子节点
node.right = creat_tree(nodes, i * 2 + 2) # 创建右子节点
return node # 返回创建的二叉树的根节点
# 输入节点列表并创建二叉树
nodes = input("输入节点root:").split(",") # 4,2,6,1,3
for i in range(len(nodes)):
if nodes[i] == "null":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
root = creat_tree(nodes, 0)
# val = int(input("输入整数值val:"))
# 二叉搜索树的最小绝对差
solution = Solution()
result = solution.getMinimumDifference(root)
print(result)
501.二叉搜索树中的众数
- 核心代码模式
# 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 __init__(self): # 构建全局变量
self.pre = None # 双指针法
self.count = 1 # 当前出现次数
self.max_count = 1 # 最大出现次数,这个初始化值必须和count相同
self.result = [] # 结果列表
def getNum(self, cur: TreeNode) -> List[int]: # 确定递归参数和返回值
# 确定递归终止条件
if not cur:
return
# 单次递归操作(中序遍历)
self.getNum(cur.left) # 左
if self.pre is not None: # 中
if self.pre.val == cur.val: # 统计相同元素个数
self.count += 1
else:
self.count = 1
self.pre = cur # 更新上一个节点,不要忘记加self
if self.count == self.max_count:
self.result.append(cur.val)
elif self.count > self.max_count:
self.result.clear() # 注意要先清空result
self.max_count = self.count
self.result.append(cur.val)
self.getNum(cur.right) # 右
return
def findMode(self, root: Optional[TreeNode]) -> List[int]:
self.getNum(root)
return self.result
236.二叉树的最近公共祖先
- 核心代码模式
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def traversal(self, cur: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode: # 确定递归参数和返回值
# 确定递归终止条件
if not cur:
return None
if p == cur or q == cur:
return cur
# 确定单步递归操作(后序遍历)
left = self.traversal(cur.left, p, q)
right = self.traversal(cur.right, p, q)
if left and right:
return cur
elif left and not right:
return left
elif not left and right:
return right
else:
return None
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
result = self.traversal(root, p, q)
return result
235.二叉搜索树的最近公共祖先
- 核心代码模式
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def traversal(self, cur: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode: # 确定递归参数和返回值
# 确定递归终止条件
if not cur:
return None
if p == cur or q == cur:
return cur
# 确定单步递归操作(后序遍历)
if min(p.val, q.val) > cur.val: # 在右子树
left = None
right = self.traversal(cur.right, p, q)
elif max(p.val, q.val) < cur.val:
left = self.traversal(cur.left, p, q) # 在左子树
right = None
else: # 在左右子树
left = self.traversal(cur.left, p, q)
right = self.traversal(cur.right, p, q)
if not left and not right: # 左右都为None
return None
elif left and not right: # 右为None
return left
elif not left and right: # 左为None
return right
else:
return cur
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
result = self.traversal(root, p, q)
return result
701.二叉搜索树的插入操作
- 核心代码模式
# 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 traversal(self, root: TreeNode, val: int) -> TreeNode: # 确定递归参数和返回值
# 确定循环终止条件(插入的节点一定可以是叶子结点)
if not root:
node = TreeNode(val)
return node
# 单次递归操作
if val > root.val:
root.right = self.traversal(root.right, val)
elif val < root.val:
root.left = self.traversal(root.left, val)
return root
def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
result = self.traversal(root, val)
return result
- ACM模式
from collections import deque
# 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 traversal(self, root: TreeNode, val: int) -> TreeNode: # 确定递归参数和返回值
# 确定循环终止条件(插入的节点一定可以是叶子结点)
if not root:
node = TreeNode(val)
return node
# 单次递归操作
if val > root.val:
root.right = self.traversal(root.right, val)
elif val < root.val:
root.left = self.traversal(root.left, val)
return root
def insertIntoBST(self, root, val):
result = self.traversal(root, val)
return result
# 层序遍历输出结果
def levelOrder(root):
if not root: # 如果二叉树为空,则直接返回空列表
return []
queue = deque([root]) # 创建队列,用于存放已经访问的二叉树节点(注意,存放的是二叉树节点,不是节点元素值)
result = [] # 存放遍历结果
# 层序遍历
while queue:
level = [] # 存放每一层遍历的结果
lenth = len(queue) # 记录每一层需要弹出的节点数量
for _ in range(lenth): # 弹出队列中的每个节点,并将该节点的左右孩子节点放入队列,注意queue长度会变,这里不能直接使用len(queue)
cur = queue.popleft()
level.append(cur.val) # 弹出当前节点
if cur.left: # 将该节点的左右孩子节点放入队列
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
result += level # 记录这一层的遍历结果
return result
def creat_tree(nodes, i):
node = None # 先创建一个空节点
if i < len(nodes) and nodes[i] is not None: # 如果要创建的节点存在且不为None
node = TreeNode(nodes[i]) # 创建该节点
node.left = creat_tree(nodes, i * 2 + 1) # 创建左子节点
node.right = creat_tree(nodes, i * 2 + 2) # 创建右子节点
return node # 返回创建的二叉树的根节点
# 输入节点列表并创建二叉树
nodes = input("输入节点root:").split(",") # 4,2,7,1,3
for i in range(len(nodes)):
if nodes[i] == "null":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
root = creat_tree(nodes, 0)
val = int(input("输入整数值val:"))
# 二叉搜索树的插入操作
solution = Solution()
result = solution.insertIntoBST(root, val)
result = levelOrder(result)
print(result)
450.删除二叉搜索树中的节点
- 核心代码模式
# 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 delete(self, root: TreeNode, key: int) -> TreeNode: # 递归参数和返回值
# 递归终止条件
if not root:
return None # 未找到要删除的节点
if key == root.val:
if not root.left and not root.right:
return None # 左空右也空
elif root.left and not root.right:
return root.left # 左不空右空
elif not root.left and root.right:
return root.right # 左空右不空
elif root.left and root.right:
cur = root.right # 左右都不空,将左子树补到右子树最左侧
while cur.left:
cur = cur.left
cur.left = root.left
return root.right
# 单次递归操作
if key < root.val:
root.left = self.delete(root.left, key)
elif key > root.val:
root.right = self.delete(root.right, key)
return root
def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
result = self.delete(root, key)
return result
- ACM模式
from collections import deque
# 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 delete(self, root: TreeNode, key: int) -> TreeNode: # 递归参数和返回值
# 递归终止条件
if not root:
return None # 未找到要删除的节点
if key == root.val:
if not root.left and not root.right:
return None # 左空右也空
elif root.left and not root.right:
return root.left # 左不空右空
elif not root.left and root.right:
return root.right # 左空右不空
elif root.left and root.right:
cur = root.right # 左右都不空,将左子树补到右子树最左侧
while cur.left:
cur = cur.left
cur.left = root.left
return root.right
# 单次递归操作
if key < root.val:
root.left = self.delete(root.left, key)
elif key > root.val:
root.right = self.delete(root.right, key)
return root
def deleteNode(self, root, key: int):
result = self.delete(root, key)
return result
# 层序遍历输出结果
def levelOrder(root):
if not root: # 如果二叉树为空,则直接返回空列表
return []
queue = deque([root]) # 创建队列,用于存放已经访问的二叉树节点(注意,存放的是二叉树节点,不是节点元素值)
result = [] # 存放遍历结果
# 层序遍历
while queue:
level = [] # 存放每一层遍历的结果
lenth = len(queue) # 记录每一层需要弹出的节点数量
for _ in range(lenth): # 弹出队列中的每个节点,并将该节点的左右孩子节点放入队列,注意queue长度会变,这里不能直接使用len(queue)
cur = queue.popleft()
level.append(cur.val) # 弹出当前节点
if cur.left: # 将该节点的左右孩子节点放入队列
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
result += level # 记录这一层的遍历结果
return result
def creat_tree(nodes, i):
node = None # 先创建一个空节点
if i < len(nodes) and nodes[i] is not None: # 如果要创建的节点存在且不为None
node = TreeNode(nodes[i]) # 创建该节点
node.left = creat_tree(nodes, i * 2 + 1) # 创建左子节点
node.right = creat_tree(nodes, i * 2 + 2) # 创建右子节点
return node # 返回创建的二叉树的根节点
# 输入节点列表并创建二叉树
nodes = input("输入节点root:").split(",") # 5,3,6,2,4,null,7
for i in range(len(nodes)):
if nodes[i] == "null":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
root = creat_tree(nodes, 0)
key = int(input("输入整数值key:"))
# 删除二叉搜索树中的节点
solution = Solution()
result = solution.deleteNode(root, key)
result = levelOrder(result)
print(result)
669.修剪二叉搜索树
- 核心代码模式
# 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 traversal(self, root: TreeNode, low: int, high: int) -> TreeNode:
# 确定递归终止条件
if not root:
return None
if root.val < low:
right = self.traversal(root.right, low, high)
return right
if root.val > high:
left = self.traversal(root.left, low, high)
return left
# 单步递归操作
root.left = self.traversal(root.left, low, high)
root.right = self.traversal(root.right, low, high)
return root
def trimBST(self, root: Optional[TreeNode], low: int, high: int) -> Optional[TreeNode]:
result = self.traversal(root, low, high)
return result
- ACM模式
from collections import deque
# 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 traversal(self, root: TreeNode, low: int, high: int) -> TreeNode:
# 确定递归终止条件
if not root:
return None
if root.val < low:
right = self.traversal(root.right, low, high)
return right
if root.val > high:
left = self.traversal(root.left, low, high)
return left
# 单步递归操作
root.left = self.traversal(root.left, low, high)
root.right = self.traversal(root.right, low, high)
return root
def trimBST(self, root, low: int, high: int):
result = self.traversal(root, low, high)
return result
# 层序遍历输出结果
def levelOrder(root):
if not root: # 如果二叉树为空,则直接返回空列表
return []
queue = deque([root]) # 创建队列,用于存放已经访问的二叉树节点(注意,存放的是二叉树节点,不是节点元素值)
result = [] # 存放遍历结果
# 层序遍历
while queue:
level = [] # 存放每一层遍历的结果
lenth = len(queue) # 记录每一层需要弹出的节点数量
for _ in range(lenth): # 弹出队列中的每个节点,并将该节点的左右孩子节点放入队列,注意queue长度会变,这里不能直接使用len(queue)
cur = queue.popleft()
level.append(cur.val) # 弹出当前节点
if cur.left: # 将该节点的左右孩子节点放入队列
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
result += level # 记录这一层的遍历结果
return result
def creat_tree(nodes, i):
node = None # 先创建一个空节点
if i < len(nodes) and nodes[i] is not None: # 如果要创建的节点存在且不为None
node = TreeNode(nodes[i]) # 创建该节点
node.left = creat_tree(nodes, i * 2 + 1) # 创建左子节点
node.right = creat_tree(nodes, i * 2 + 2) # 创建右子节点
return node # 返回创建的二叉树的根节点
# 输入节点列表并创建二叉树
nodes = input("输入节点root:").split(",") # 5,3,6,2,4,null,7
for i in range(len(nodes)):
if nodes[i] == "null":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
root = creat_tree(nodes, 0)
low = int(input("输入整数值low:"))
high = int(input("输入整数值high:"))
# 修剪二叉搜索树
solution = Solution()
result = solution.trimBST(root, low, high)
result = levelOrder(result)
print(result)
108.将有序数组转换为二叉搜索树
- 核心代码模式
# 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 __init__(self):
self.nums = []
def getTree(self, left: int, right: int) -> TreeNode: # 递归参数和返回值
# 递归终止条件
if left >= right:
return None
# 单步递归操作(前序遍历)
mid = (left + right) // 2
root = TreeNode(self.nums[mid])
root.left = self.getTree(left, mid)
root.right = self.getTree(mid + 1, right)
return root
def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
self.nums = nums
result = self.getTree(0, len(nums))
return result
- ACM模式
from collections import deque
# 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 __init__(self):
self.nums = []
def getTree(self, left: int, right: int) -> TreeNode: # 递归参数和返回值
# 递归终止条件
if left >= right:
return None
# 单步递归操作(前序遍历)
mid = (left + right) // 2
root = TreeNode(self.nums[mid])
root.left = self.getTree(left, mid)
root.right = self.getTree(mid + 1, right)
return root
def sortedArrayToBST(self, nums):
self.nums = nums
result = self.getTree(0, len(nums))
return result
# 层序遍历输出结果
def levelOrder(root):
if not root: # 如果二叉树为空,则直接返回空列表
return []
queue = deque([root]) # 创建队列,用于存放已经访问的二叉树节点(注意,存放的是二叉树节点,不是节点元素值)
result = [] # 存放遍历结果
# 层序遍历
while queue:
level = [] # 存放每一层遍历的结果
lenth = len(queue) # 记录每一层需要弹出的节点数量
for _ in range(lenth): # 弹出队列中的每个节点,并将该节点的左右孩子节点放入队列,注意queue长度会变,这里不能直接使用len(queue)
cur = queue.popleft()
level.append(cur.val) # 弹出当前节点
if cur.left: # 将该节点的左右孩子节点放入队列
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
result += level # 记录这一层的遍历结果
return result
# 输入节点列表并创建二叉树
nodes = input("输入节点root:").split(",") # 5,3,6,2,4,null,7
for i in range(len(nodes)):
if nodes[i] == "null":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
# 将有序数组转换为二叉搜索树
solution = Solution()
result = solution.sortedArrayToBST(nodes)
result = levelOrder(result)
print(result)
538.把二叉搜索树转换为累加树
- 核心代码模式
# 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 __init__(self):
self.pre = TreeNode(0) # 记录前一个节点
def traversal(self, cur: TreeNode) -> TreeNode: # 递归参数和返回值
# 递归终止条件
if not cur:
return
# 单步递归操作
self.traversal(cur.right) # 右
cur.val += self.pre.val # 中
self.pre = cur
self.traversal(cur.left) # 左
return cur
def convertBST(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
result = self.traversal(root)
return result
- ACM模式
from collections import deque
# 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 __init__(self):
self.pre = TreeNode(0) # 记录前一个节点
def traversal(self, cur: TreeNode) -> TreeNode: # 递归参数和返回值
# 递归终止条件
if not cur:
return
# 单步递归操作
self.traversal(cur.right) # 右
cur.val += self.pre.val # 中
self.pre = cur
self.traversal(cur.left) # 左
return cur
def convertBST(self, root):
result = self.traversal(root)
return result
# 层序遍历输出结果
def levelOrder(root):
if not root: # 如果二叉树为空,则直接返回空列表
return []
queue = deque([root]) # 创建队列,用于存放已经访问的二叉树节点(注意,存放的是二叉树节点,不是节点元素值)
result = [] # 存放遍历结果
# 层序遍历
while queue:
level = [] # 存放每一层遍历的结果
lenth = len(queue) # 记录每一层需要弹出的节点数量
for _ in range(lenth): # 弹出队列中的每个节点,并将该节点的左右孩子节点放入队列,注意queue长度会变,这里不能直接使用len(queue)
cur = queue.popleft()
level.append(cur.val) # 弹出当前节点
if cur.left: # 将该节点的左右孩子节点放入队列
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
result += level # 记录这一层的遍历结果
return result
def creat_tree(nodes, i):
node = None # 先创建一个空节点
if i < len(nodes) and nodes[i] is not None: # 如果要创建的节点存在且不为None
node = TreeNode(nodes[i]) # 创建该节点
node.left = creat_tree(nodes, i * 2 + 1) # 创建左子节点
node.right = creat_tree(nodes, i * 2 + 2) # 创建右子节点
return node # 返回创建的二叉树的根节点
# 输入节点列表并创建二叉树
nodes = input("输入节点root:").split(",") # 1,0,2
for i in range(len(nodes)):
if nodes[i] == "null":
nodes[i] = None
else:
nodes[i] = int(nodes[i])
root = creat_tree(nodes, 0)
# 将二叉搜索树转换成累加树
solution = Solution()
result = solution.convertBST(root)
result = levelOrder(result)
print(result)