class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
if(root==null){
return result;
}
Queue<TreeNode> queue = new LinkedList();
queue.add(root);
while(!queue.isEmpty()){
List<Integer> list = new ArrayList();
//size控制当前队列的长度
int size = queue.size();
for(int i=0;i<size;i++){
TreeNode node = queue.poll();
list.add(node.val); //当前队列元素的值存入结果集合
if(node.left!=null){ //加入子节点操作,等待下次循环
queue.add(node.left);
}
if(node.right!=null){ //加入子节点操作,等待下次循环
queue.add(node.right);
}
}
result.add(list);
}
return result;
}
}
参考官方答案,采用广度优先搜索的基础路基,巧妙的优化。
参考上图,层序遍历,就是一层一层的变量,最简单的实现方式就是采用2个队列(数组也行),第一个队列A用来存储上一层的元素,第二个队列B用来存储下一层的子元素队列,当队列A被迭代处理完后,子元素都加入队列B了,队列A被丢弃。如此往复,当队列B被迭代处理完后,他的子元素也被加入新的队列C,队列B被丢弃。
问题是上面的方案空间复杂度比较高,每次需要创建新的数组来存储下一层的子元素。当然可以通过复用已有数组来实现,比如队列C不需要新建,复用A,这样只需2个队列。
那么有没有更优化的方案呢?有!利用一个队列即可:
- size=2,表示当前队列的大小,即父层元素的数量,2和3
- 当元素2被poll出来后,子元素4和5被加入到队列尾部
- 当元素3被poll出来后,子元素6被加入到队列尾部
- 由于size可以控制for循环的次数,当退出for时,说明一次循环结束
- 下一次循环,队列里面的元素是456,size=3,往复循环