思路:
广度优先遍历
代码:
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res=new ArrayList<>();
//是Queue不是List
Queue<TreeNode> queue=new LinkedList<>();
if(root!=null){
queue.add(root);
}
while(!queue.isEmpty()){
List<Integer> path=new ArrayList<>();
int len=queue.size();
//把len循环完才把一个path放入res
for(int i=len;i>0;i--){
//在循环内弹出值
TreeNode node=queue.poll();
//把每个父节点都加入path
path.add(node.val);
if(node.left!=null){
//只是加入队列,不是加入path
queue.add(node.left);
}
if(node.right!=null){
queue.add(node.right);
}
}
res.add(path);
}
return res;
}
}
分解:
1)创建队列queue时是写Queue而不是List
2)用一个len记录每一层的节点
3)把len循环完才把一个path放入res
4)在循环内弹出queue的值,把每个父节点都加入path。而左右节点的遍历只是放入队列而不是path
5)path=new LinkedList前面如果写的是Deque,后面res.add(path)类型不匹配,加入不了,要写成LinkedList
6)因为不是递归,要保持path每次都清空,就要将new 的操作放在while循环体里
复杂度分析:
时间复杂度:O(N) 每个节点都只放入、弹出一次O(2N)
空间复杂度:O(N) 额外使用了一个队列,res不是额外空间,是必须空间,所以不算在空间复杂度中。最差的情况当树为平衡二叉树时,最多有N/2个树节点同时在queue中