昨晚没写出来,但是把思路给理出来了,今天照着昨晚的思路,很快写出来了,但是当我觉得更好的时候,又改了一下,于是就过去两个小时了,
思路:
首先我是使用两个队列,一个队列专门用来取出下一层的节点,而另一个队列用来取值,放入到list中,注意的是这个list的类型也是list,这个过程中最长的时间就是qu2 = qu1,一开始我以为的是赋值,也就直接这么写了,哪知道这是赋地址,就是说qu1弹出,qu2也会弹出,这个bug找的真久,以后需要注意点,因此我将qu2的赋值放在了里面
代码:
public static List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> target = new ArrayList<>();
if(root == null){
return target;
}else {
//设置最终要保存在每一层的节点的值
Map hash = new HashMap<Integer,List<Integer>>();
//设置外层的一个队列
Queue<TreeNode> qu1 = new LinkedList<TreeNode>();
//设置内层的一个队列
Queue<TreeNode> qu2 = new LinkedList<TreeNode>();
//先把根节点放入到外层队列中
qu1.offer(root);
//先把根节点放入外循环
int i = 1;
List<Integer> mid1 = new ArrayList<>();
mid1.add(root.val);
target.add(mid1);
int j = 1;
while(true){
//将外循环的所有左右节点都放入内存队列
while (!qu1.isEmpty()) {
//设置一个临时变量存储中间节点
root = qu1.poll();
if(root.left !=null){
qu2.offer(root.left);
}
if(root.right !=null){
qu2.offer(root.right);
}
}
List<Integer> mid = new ArrayList<>();
while (!qu2.isEmpty()) {
root = qu2.poll();
qu1.offer(root);
//保存中间的结果的list
mid.add(root.val);
}
if(mid.size()>0){
target.add(mid);
}
if(qu1.isEmpty()){
break;
}
}
Collections.reverse(target);
return target;
}
}
排名靠前的代码:发现最后的反转有异曲同工之妙,哈哈哈,一开始我是循环的,后来想着优化就把list直接调用api进行反转了。
class Solution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
if (root == null) {
return new ArrayList<>();
}
List<List<Integer>> result = new ArrayList<>();
Queue<TreeNode> list = new LinkedList<>();
list.add(root);
while (list.size() != 0) {
int size = list.size();
ArrayList<Integer> in = new ArrayList<>();
for (int i = 0; i < size; i++) {
TreeNode cur = list.poll();
in.add(cur.val);
if (cur.left != null) {
list.offer(cur.left);
}
if (cur.right != null) {
list.offer(cur.right);
}
}
result.add(in);
}
Collections.reverse(result);
return result;
}
}