搜索与回溯
- 剑指 Offer 32 - I. 从上到下打印二叉树
- 层序遍历 广搜 BFS
- collections
- 双端队列 deque
- 剑指 Offer 32 - II. 从上到下打印二叉树 II
- 剑指 Offer 32 - III. 从上到下打印二叉树 III
剑指 Offer 32 - I. 从上到下打印二叉树
题;从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。
层序遍历 广搜 BFS
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def levelOrder(self, root: TreeNode) -> List[int]:
if not root:return []
res,queue=[], collections.deque()
queue.append(root)#先加入一个根节点
while queue:
node=queue.popleft()#
res.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return res
'''
Q:完整的输入输出如何实现?
'''
#!希望后续补充实现完整输入输出!!
复杂度分析:
时间复杂度 O(N) : N为二叉树的节点数量,即 BFS 需循环 N 次。
空间复杂度 O(N): 最差情况下,即当树为平衡二叉树时,最多有 N/2个树节点同时在 queue 中,使用 O(N)大小的额外空间。
collections
作为 Python 的内建集合模块,实现了许多十分高效的特殊容器数据类型
双端队列 deque
append():
从右端添加元素,与list相同
appendleft():
从左端添加元素
extend():
从右端逐个添加可迭代对象,与list相同,Python中的可迭代对象有:列表、元组、字典、字符串
extendleft():
pop()
:移除列表中的一个元素(默认最右端的一个元素),并且返回该元素的值(与list同),如果没有元素,将会报出IndexError
popleft()
:
count()
:统计队列中的元素个数(与list同)
insert(index,obj)
:在指定位置插入元素(与list同)
rotate(n)
: 从右侧反转n步,如果n为负数,则从左侧反转。
d.rotate(1)
等于 d.appendleft(d.pop())
maxlen:
只读的属性,deque限定的最大长度,如果无,就返回None。
当限制长度的deque增加超过限制数的项时, 另一边的项会自动删除。
remove()
:移除第一次出现的元素,如果没有找到,报出ValueError
clear()
:将deque中的元素全部删除,最后长度为0
剑指 Offer 32 - II. 从上到下打印二叉树 II
题 从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。
思考:
BFS 循环: 当队列 queue 为空时跳出;
新建一个临时列表 tmp ,用于存储当前层打印结果;
当前层打印循环: 循环次数为当前层节点数(即队列 queue 长度);
出队: 队首元素出队,记为 node;
打印: 将 node.val 添加至 tmp 尾部;
添加子节点: 若 node 的左(右)子节点不为空,则将左(右)子节点加入队列 queue ;
将当前层结果 tmp 添加入 res 。
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
if not root:return []
res,queue=[], collections.deque()
queue.append(root)#先加入一个根节点
while queue:
tmp=[]
for i in range(len(queue)):
node=queue.popleft()
tmp.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
res.append(tmp)
return res
复杂度分析:
时间复杂度 O(N)。
空间复杂度 O(N)。
代码参考:https://leetcode.cn/problems/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof/solutions/137255/mian-shi-ti-32-ii-cong-shang-dao-xia-da-yin-er-c-5/
剑指 Offer 32 - III. 从上到下打印二叉树 III
题 请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。
思考:这题直接设一个数字标注层数是奇是偶,对应给tmp[]逆序是不可以的,因为后序层遍历的顺序会变!!
所以应将主要程序重复,但是一个先左后右,一个先右后左,中间记得判断是否空了;
或者tmp也是双端队列,第一个点放入tmp,如果当前是偶数层,下一个点从左边插入。 最后append到res中时记得把tmp转为list【如下面代码】
#按层数奇偶
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
if not root:return []
res,queue=[], collections.deque()
queue.append(root)#先加入一个根节点
while queue:
tmp=collections.deque()
for i in range(len(queue)):
node=queue.popleft()#第一个点先放进去
if len(res)%2==1:#此层是偶数层,节点往左边插入
tmp.appendleft(node.val)
else:tmp.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
res.append(list(tmp))
return res