一、二叉树的层序遍历 讲解链接
关于二叉树层序遍历的十道题:
题目1链接:102. 二叉树的层序遍历
迭代法:
class Solution:
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
if not root:
return []
from collections import deque
queue = deque([root]) #记录中间过程的队列
res = [] #记录最终结果
while queue:
size = len(queue) #记录每层节点个数
vec = [] #记录每一层结果
for _ in range(size): #记录当前层是否已遍历完
node = queue.popleft()
vec.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
res.append(vec)
return res
题目2链接:107. 二叉树的层序遍历 II
题意:给二叉树的根节点 root
,返回其节点值 自底向上的层序遍历。(即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
因此将上一题代码结果翻转即可。
class Solution:
def levelOrderBottom(self, root: Optional[TreeNode]) -> List[List[int]]:
if not root:
return []
from collections import deque
queue = deque([root]) #记录中间过程的队列
res = [] #记录最终结果
while queue:
size = len(queue) #记录每层节点个数
vec = [] #记录每一层结果
for _ in range(size): #记录当前层是否已遍历完
node = queue.popleft()
vec.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
res.append(vec)
res.reverse()
return res
题目3链接:199. 二叉树的右视图
记录每一层最右边的节点值即可
class Solution:
def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
if not root:
return []
from collections import deque
queue = deque([root])
res = []
while queue:
cur = queue[-1]
res.append(cur.val)
size = len(queue)
for _ in range(size):
cur = queue.popleft()
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
return res
题目4链接:637. 二叉树的层平均值
将第一题记录每层节点数值,改成记录每层总和数即可
class Solution:
def averageOfLevels(self, root: Optional[TreeNode]) -> List[float]:
res = [] #记录最终结果
if not root:
return res
from collections import deque
queue = deque([root]) #记录中间过程的队列
while queue:
size = len(queue) #记录每层节点个数
total = 0 #记录每一层和
for _ in range(size): #记录当前层是否已遍历完
cur = queue.popleft()
total += cur.val
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
res.append(total/size)
return res
题目5链接:429. N 叉树的层序遍历
将加入左右子树的代码改成extend所有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:
size = len(queue) #记录每层节点个数
vec = [] #记录每一层结果
for _ in range(size): #记录当前层是否已遍历完
cur = queue.popleft()
vec.append(cur.val)
if cur.children:
queue.extend(cur.children) #这里不用append,不然会把全部孩子看成一个整体加进去
res.append(vec)
return res
题目6链接:515. 在每个树行中找最大值
将第一题记录每层节点数值,改成记录每层当前最大值即可
class Solution:
def largestValues(self, root: Optional[TreeNode]) -> List[int]:
res = []
if not root:
return res
from collections import deque
queue = deque([root])
while queue:
maxi = float('-inf') #记录每层最大值
size = len(queue)
for _ in range(size):
cur = queue.popleft()
maxi = max(maxi, cur.val) #比较本层之前最大值和当前值孰大
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
res.append(maxi)
return res
题目7链接:116. 填充每个节点的下一个右侧节点指针
层序遍历解法:
class Solution:
def connect(self, root: 'Optional[Node]') -> 'Optional[Node]':
if not root:
return None
from collections import deque
queue = deque([root])
while queue:
size = len(queue)
for _ in range(size):
cur = queue.popleft()
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
if _ == size-1: #每层最后一个节点不处理
break
cur.next = queue[0]
return root
题目8链接:117.填充每个节点的下一个右侧节点指针II
和上题的区别是把满二叉树改成了二叉树,但方法和代码是一样的。
class Solution:
def connect(self, root: 'Node') -> 'Node':
if not root:
return None
from collections import deque
queue = deque([root])
while queue:
size = len(queue)
for _ in range(size):
cur = queue.popleft()
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
if _ == size-1: #每层最后一个节点不处理
break
cur.next = queue[0]
return root
题目9链接:104. 二叉树的最大深度
迭代法和第一题代码基本一样,只需要改变最后返回记录的列表长度
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
from collections import deque
queue = deque([root]) #记录中间过程的队列
res = [] #记录最终结果
while queue:
size = len(queue) #记录每层节点个数
vec = [] #记录每一层结果
for _ in range(size): #记录当前层是否已遍历完
cur = queue.popleft()
vec.append(cur.val)
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
res.append(vec)
return len(res)
题目10链接:111. 二叉树的最小深度
class Solution:
def minDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
from collections import deque
queue = deque([(root,1)])
while queue:
cur, depth = queue.popleft()
if not cur.left and not cur.right:
return depth
if cur.left:
queue.append((cur.left, depth+1))
if cur.right:
queue.append((cur.right,depth+1))
return 0
二、226.翻转二叉树 讲解链接
递归前序遍历:
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.invertTree(root.right)
return root
深度优先前序遍历:
class Solution:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
if not root:
return None
st = [root] #栈
while st:
cur = st.pop()
cur.left, cur.right = cur.right, cur.left
if cur.right:
st.append(cur.right)
if cur.left:
st.append(cur.left)
return root
广度优先层序遍历:
class Solution:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
if not root:
return None
from collections import deque
queue = deque([root])
while queue:
size = len(queue)
for _ in range(size):
cur = queue.popleft()
cur.left, cur.right = cur.right, cur.left
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
return root
三、101. 对称二叉树 讲解链接
后序遍历,递归解法:
class Solution:
def isSymmetric(self, root: Optional[TreeNode]) -> bool:
if not root:
return True
return self.compare(root.left, root.right)
def compare(self, left, right):
if not left and right: return False
elif left and not right: return False
elif not left and not right: return True
elif left.val != right.val: return False
outside = self.compare(left.left, right.right)
inside = self.compare(left.right, right.left)
return outside and inside