这是基于代码随想录的每日打卡
144. 二叉树的前序遍历
给你二叉树的根节点 root
,返回它节点值的 前序 遍历。
示例 1:
输入: root = [1,null,2,3]
输出:[1,2,3]
解释:
示例 2:
输入: root = [1,2,3,4,5,null,8,null,null,6,7,9]
输出:[1,2,4,5,6,7,3,8,9]
解释:
示例 3:
输入: root = []
输出:[]
示例 4:
输入: root = [1]
输出:[1]
递归法
# 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]:
res=[]
def pre(root):
if root==None:
return
res.append(root.val)
pre(root.left)
pre(root.right)
pre(root)
return res
运行结果
非递归法:迭代法
前序遍历是中左右,每次先处理的是中间节点,那么先将根节点放入栈中,然后将右孩子加入栈,再加入左孩子。
为什么要先加入 右孩子,再加入左孩子呢? 因为这样出栈的时候才是中左右的顺序。
代码
# 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]:
if root==None:
return []
# 先在栈中放入根节点
stack=[root]
# 存放结果数组
res=[]
# 如果栈不为空
while stack:
# 弹出栈顶元素并将元素值存入结果
node=stack.pop()
res.append(node.val)
# 先存右孩子
if node.right:
stack.append(node.right)
if node.left:
stack.append(node.left)
return res
运行结果
145. 二叉树的后序遍历
给你一棵二叉树的根节点 root
,返回其节点值的 后序遍历 。
示例 1:
输入: root = [1,null,2,3]
输出:[3,2,1]
解释:
示例 2:
输入: root = [1,2,3,4,5,null,8,null,null,6,7,9]
输出:[4,6,7,5,2,9,8,3,1]
解释:
示例 3:
输入: root = []
输出:[]
示例 4:
输入: root = [1]
输出:[1]
递归法
# 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]:
res=[]
def back(root):
if root==None:
return
back(root.left)
back(root.right)
res.append(root.val)
back(root)
return res
运行结果
非递归法:迭代法
先序遍历是中左右,后序遍历是左右中,那么我们只需要调整一下先序遍历的代码顺序,就变成中右左的遍历顺序,然后在反转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 root==None:
return []
stack=[root]
res=[]
while stack:
node=stack.pop()
res.append(node.val)
# 先存入右节点
if node.left:
stack.append(node.left)
if node.right:
stack.append(node.right)
# 结果逆序输出
return res[::-1]
运行结果
94. 二叉树的中序遍历
给定一个二叉树的根节点 root
,返回 它的 中序 遍历 。
示例 1:
输入:root = [1,null,2,3]
输出:[1,3,2]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
递归法
# 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]:
res=[]
def mid(root):
if root==None:
return
mid(root.left)
res.append(root.val)
mid(root.right)
mid(root)
return res
运行结果
非递归法:
前序遍历的顺序是中左右,先访问的元素是中间节点,要处理的元素也是中间节点,所以在中序遍历中我们不能跟后序遍历一样,对前序遍历换个顺序就ok了。
中序遍历是左中右,先访问的是二叉树顶部的节点,然后一层一层向下访问,直到到达树左面的最底部,再开始处理节点(也就是再把节点的数值放进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 root==None:
return []
stack=[]
res=[]
# 开始时指针指向根节点
cur=root
# 当指针不为空或者栈不为空
while cur or stack:
# 让指针一直指向左孩子,并且遍历到的节点要存入栈
if cur:
stack.append(cur)
cur=cur.left
# 直到左孩子为空,则将栈顶元素弹出(此节点没有左孩子)
else:
# 弹出栈顶元素值加入结果
node=stack.pop()
res.append(node.val)
# 指针指向右孩子,继续循环
cur=node.right
return res
运行结果
102. 二叉树的层序遍历
给你二叉树的根节点 root
,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]
示例 2:
输入:root = [1]
输出:[[1]]
示例 3:
输入: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 levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
from collections import deque
# 如果根节点为空则返回空数组
if root==None:
return []
que=deque()
# 队列先加入根节点
que.append(root)
# 存放全部层的结果
res=[]
# 当队列元素不为空
while que:
# 存放每一层的结果
small_res=[]
# 记录每一层的个数
size=len(que)
# 循环遍历每一层的节点
for _ in range(size):
node=que.popleft()
# 将当前层的每个节点值存入
small_res.append(node.val)
# 如果有左右孩子则加入队列
if node.left:
que.append(node.left)
if node.right:
que.append(node.right)
res.append(small_res)
return res
运行结果
107. 二叉树的层序遍历 II
给你二叉树的根节点 root
,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:[[15,7],[9,20],[3]]
示例 2:
输入:root = [1]
输出:[[1]]
示例 3:
输入: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 levelOrderBottom(self, root: Optional[TreeNode]) -> List[List[int]]:
if root==None:
return []
from collections import deque
que=deque()
que.append(root)
res=[]
while que:
size=len(que)
small_res=[]
for _ in range(size):
node=que.popleft()
small_res.append(node.val)
if node.left:
que.append(node.left)
if node.right:
que.append(node.right)
res.append(small_res)
# 跟前一道的区别就是逆序输出
return res[::-1]
运行结果
199. 二叉树的右视图
给定一个二叉树的 根节点 root
,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
示例 1:
输入: root = [1,2,3,null,5,null,4]
输出:[1,3,4]
解释:
示例 2:
输入: root = [1,2,3,4,null,null,null,5]
输出:[1,3,4,5]
解释:
示例 3:
输入: root = [1,null,3]
输出:[1,3]
示例 4:
输入: 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 rightSideView(self, root: Optional[TreeNode]) -> List[int]:
if root==None:
return []
from collections import deque
que=deque()
que.append(root)
res=[]
while que:
size=len(que)
# 先把每一层除了最右边的popleft出来,同时在队列中加入它们的孩子
for _ in range(size-1):
node=que.popleft()
if node.left:
que.append(node.left)
if node.right:
que.append(node.right)
# 这个节点就是最右边的节点了
node=que.popleft()
res.append(node.val)
if node.left:
que.append(node.left)
if node.right:
que.append(node.right)
return res
运行结果
637. 二叉树的层平均值
给定一个非空二叉树的根节点 root
, 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5
以内的答案可以被接受。
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:[3.00000,14.50000,11.00000]
解释:第 0 层的平均值为 3,第 1 层的平均值为 14.5,第 2 层的平均值为 11 。
因此返回 [3, 14.5, 11] 。
示例 2:
输入:root = [3,9,20,15,7]
输出:[3.00000,14.50000,11.00000]
代码
# 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]:
# 由于本题限制节点数大于1,故不需要判断root==None的情况
from collections import deque
que=deque()
que.append(root)
res=[]
while que:
size=len(que)
tmp=[]
for _ in range(size):
node=que.popleft()
tmp.append(node.val)
if node.left:
que.append(node.left)
if node.right:
que.append(node.right)
res.append(sum(tmp)/size)
return res
运行结果
429. N 叉树的层序遍历
给定一个 N 叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。
树的序列化输入是用层序遍历,每组子节点都由 null 值分隔(参见示例)。
示例 1:
输入:root = [1,null,3,2,4,null,5,6]
输出:[[1],[3,2,4],[5,6]]
示例 2:
输入:root = [1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14]
输出:[[1],[2,3,4,5],[6,7,8,9,10],[11,12,13],[14]]
代码
"""
# Definition for a Node.
class Node:
def __init__(self, val: Optional[int] = None, children: Optional[List['Node']] = None):
self.val = val
self.children = children
"""
class Solution:
def levelOrder(self, root: 'Node') -> List[List[int]]:
if root==None:
return []
from collections import deque
que=deque()
que.append(root)
res=[]
while que:
size=len(que)
small_res=[]
for _ in range(size):
node=que.popleft()
small_res.append(node.val)
# 将当前节点的每一个孩子存入队列
for child in node.children:
que.append(child)
res.append(small_res)
return res
运行结果
515. 在每个树行中找最大值
给定一棵二叉树的根节点 root
,请找出该二叉树中每一层的最大值。
示例1:
输入: root = [1,3,2,5,3,null,9]
输出: [1,3,9]
示例2:
输入: root = [1,2,3]
输出: [1,3]
代码
# 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 root==None:
return []
from collections import deque
que=deque()
que.append(root)
res=[]
while que:
size=len(que)
# 遍历每一层时把最大值设置为负无穷
max_val=float('-inf')
for _ in range(size):
node=que.popleft()
# 将最大值与当前层的每个节点比较
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
运行结果
116. 填充每个节点的下一个右侧节点指针
给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL
。
初始状态下,所有 next 指针都被设置为 NULL
。
示例 1:
输入:root = [1,2,3,4,5,6,7]
输出:[1,#,2,3,#,4,5,6,7,#]
解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。序列化的输出按层序遍历排列,同一层节点由 next 指针连接,'#' 标志着每一层的结束。
示例 2:
输入:root = []
输出:[]
代码
"""
# 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 root==None:
return root
from collections import deque
que=deque()
que.append(root)
while que:
# 设置一个前置节点
pre=None
size=len(que)
for _ in range(size):
cur=que.popleft()
# 如果前置结果不是空则说明当前不是第一个节点,所以要连接操作
if pre:
pre.next=cur
# 前置节点移动
pre=cur
if cur.left:
que.append(cur.left)
if cur.right:
que.append(cur.right)
return root
运行结果
117. 填充每个节点的下一个右侧节点指针 II
给定一个二叉树:
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL
。
初始状态下,所有 next 指针都被设置为 NULL
。
示例 1:
输入:root = [1,2,3,4,5,null,7]
输出:[1,#,2,3,#,4,5,7,#]
解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。序列化输出按层序遍历顺序(由 next 指针连接),'#' 表示每层的末尾。
示例 2:
输入:root = []
输出:[]
代码
"""
# 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 root==None:
return root
from collections import deque
que=deque()
que.append(root)
while que:
# 设置一个前置节点
pre=None
size=len(que)
for _ in range(size):
cur=que.popleft()
# 如果前置结果不是空则说明当前不是第一个节点,所以要连接操作
if pre:
pre.next=cur
# 前置节点移动
pre=cur
if cur.left:
que.append(cur.left)
if cur.right:
que.append(cur.right)
return root
运行结果
104. 二叉树的最大深度
给定一个二叉树 root
,返回其最大深度。
二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:3
示例 2:
输入:root = [1,null,2]
输出:2
代码
# 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 root==None:
return 0
from collections import deque
que=deque()
que.append(root)
depth=0
while que:
# 每一层加1
depth+=1
size=len(que)
for _ in range(size):
node=que.popleft()
if node.left:
que.append(node.left)
if node.right:
que.append(node.right)
return depth
运行结果
111. 二叉树的最小深度
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明: 叶子节点是指没有子节点的节点。
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:2
示例 2:
输入:root = [2,null,3,null,4,null,5,null,6]
输出:5
代码
# 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 root==None:
return 0
from collections import deque
que=deque()
que.append(root)
depth=0
while que:
depth+=1
size=len(que)
for _ in range(size):
node=que.popleft()
if node.left:
que.append(node.left)
if node.right:
que.append(node.right)
# 若左右节点都没有,则为叶子节点,则直接返回深度值
if not node.left and not node.right:
return depth
return depth
运行结果
有问题欢迎评论或私信