一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第21天,点击查看活动详情。
题目:就是将二叉树进行层序遍历,只不过变了输出的格式。其中II要求的输出是同一层的节点在一个list里面,III 要求按照层数的奇数偶数从左向右或者从右向左输出答案。
解题思路
思路很简单,首先说II,既然要求每一层的节点都在一层,那么我们直接记录每层节点数量即可,使用一个list保存当前层的结果,如果判定当前层节点已遍历完成则直接加入最终结果集,方法是使用一个变量记录每层节点,每当此变量变成0即本层已遍历完成,就将临时链表重置,并且维护这个变量,将此变量的值更新为队列的长度,不断循环更新此变量即可。而对于III的要求,我们可以用另一个变量来判断当前层属于第几层,奇数层则从右向左输出,偶数层则从左向右输出,那么在II的代码上只需加入最终结果的时候将list根据层数的判断是否需要进行反转,对于奇数将反转后的结果加入集合即可。根据上面的思路将代码进行合并可得最终III的代码为:
public List<List<Integer>> levelOrder3(TreeNode root) {
if(root == null) return new ArrayList<>();
ArrayList<List<Integer>> res = new ArrayList<>();
ArrayDeque<TreeNode> queue = new ArrayDeque<>();
queue.offer(root);
int size = 1;
int cur = 0;
ArrayList<Integer> temp = new ArrayList<>();
while(!queue.isEmpty()){
TreeNode node = queue.poll();
temp.add(node.val);
size--;
if(node.left!=null){
queue.offer(node.left);
}
if(node.right!=null){
queue.offer(node.right);
}
if(size==0){
if(cur % 2==1){
Collections.reverse(temp);
res.add(temp);
}else {
res.add(temp);
}
cur++;
size = queue.size();
temp = new ArrayList<>();
}
}
return res;
}
上述用到了Collections,实际上保存临时结果集我们可以采用LinkListed,因为LinkListed对于插入有两种方式,头插法和尾插法,这刚好对应了反转结果,当当前层为偶数的时候,我们可以采用尾插法,反之使用头插法即可,这样也能得到最终结果。