目录
1. 题目描述
给定一个 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]]
提示:
- 树的高度不会超过
1000
- 树的节点总数在
[0, 10^4]
之间
2. 解题分析
层序遍历通常采用广度优先搜索。
将节点逐个放入队列,然后按FIFO的顺序取出。每个节点取出时又将其子节点放入队列。FIFO的存取顺序保证了同一层的连续出来,而且浅层出来得早(根节点最早出来,叶子节点晚出来)。
存入队列时,以(节点,layer)的元组队的形式存入,这样取出时,按照其所属layer进行各层列表统计。用ans表示存储结果的两层嵌套列表,各节点所属layer即用于它所属的子列表在顶层列表中的索引。
3. 代码实现
"""
# Definition for a Node.
class Node:
def __init__(self, val=None, children=None):
self.val = val
self.children = children
"""
from collections import deque
class Solution:
def levelOrder(self, root: 'Node') -> List[List[int]]:
if root == None:
return []
q = deque()
ans = []
q.append((root,0))
while len(q) > 0:
# deque.popleft() together with deque.append() to form a FIFO
node,layer = q.popleft()
if len(ans) <= layer:
# Is the first node of the current layer
ans.append([node.val])
else:
ans[layer].append(node.val)
for child in node.children:
q.append((child,layer+1))
return ans
执行用时:48 ms, 在所有 Python3 提交中击败了92.84%的用户
内存消耗:17.1 MB, 在所有 Python3 提交中击败了6.50%的用户
以上内存性能差的原因估计是我在队列中存储了layer信息?
另一种替代方案是,不显式地存储layer信息,对每一层的节点数另行计数跟踪。比如说,root存入时,根据root的子节点个数(即len(root.children))知道第2层(layer=1)的节点个数;然后,在从队列中取出节点数,通过计数就是什么时候将第2层取完,取第2层节点的同时根据各node的children的个数累计第3层(layer=2)的节点个数;。。。以下依此类推。
这样虽然内存复杂度仍然是,但是常数系数小。不过感觉这种coding稍微麻烦一些。
回到主目录:笨牛慢耕的Leetcode解题笔记(动态更新。。。)