描述
给定一个二叉树,返回该二叉树的之字形层序遍历,(第一层从左向右,下一层从右向左,一直这样交替)
思路1:队列层序遍历
public class Solution {
public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer>> ret = new ArrayList<>();
if(pRoot == null) {
return ret;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(pRoot);
while(!queue.isEmpty()) {
ArrayList<Integer> list = new ArrayList<>();
// 记录当前队列长度
for(int i = queue.size(); i > 0; i--) {
TreeNode node = queue.poll();
if(node.left != null) {
queue.offer(node.left);
}
if(node.right != null) {
queue.offer(node.right);
}
//奇数层插入头部
if(ret.size() % 2 == 1) {
list.add(0, node.val);
} else {
list.add(node.val);
}
}
ret.add(list);
}
return ret;
}
}
每次循环都要计算当前是奇数层还是偶数层。
优化1:使用flag标记,不断取反
public class Solution {
public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer>> ret = new ArrayList<>();
if(pRoot == null) {
return ret;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(pRoot);
boolean addHead = false;
while(!queue.isEmpty()) {
ArrayList<Integer> list = new ArrayList<>();
for(int i = queue.size(); i > 0; i--) {
TreeNode node = queue.poll();
if(node.left != null) {
queue.offer(node.left);
}
if(node.right != null) {
queue.offer(node.right);
}
if(addHead) {
list.add(0, node.val);
} else {
list.add(node.val);
}
}
ret.add(list);
addHead = !addHead;
}
return ret;
}
}
ArrayList每次插入头部,都需要拷贝数组,效率较低
优化2:遍历完之后再统一对列表进行反转
public class Solution {
public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer>> ret = new ArrayList<>();
if(pRoot == null) {
return ret;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(pRoot);
boolean addHead = false;
while(!queue.isEmpty()) {
ArrayList<Integer> list = new ArrayList<>();
for(int i = queue.size(); i > 0; i--) {
TreeNode node = queue.poll();
if(node.left != null) {
queue.offer(node.left);
}
if(node.right != null) {
queue.offer(node.right);
}
list.add(node.val);
}
if(addHead) {
Collections.reverse(list);
}
ret.add(list);
addHead = !addHead;
}
return ret;
}
}
思路2:使用双端队列
1
2、3
4、5、6、7
public class Solution {
public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer>> ret = new ArrayList<>();
if(pRoot == null) {
return ret;
}
Deque<TreeNode> deque = new LinkedList<>();
deque.offer(pRoot);
while(!deque.isEmpty()) {
ArrayList<Integer> list = new ArrayList<>();
// 奇数层,从头开始取,新元素加入尾部
for(int i = deque.size(); i > 0; i--) {
TreeNode node = deque.removeFirst();
// 先取出左节点
if(node.left != null) {
deque.addLast(node.left);
}
if(node.right != null) {
deque.addLast(node.right);
}
list.add(node.val);
}
ret.add(list);
if(deque.isEmpty()) {
break;
}
// 偶数层,从尾部取出,新元素加入头部
list = new ArrayList<>();
for(int i = deque.size(); i > 0; i--) {
TreeNode node = deque.removeLast();
// 先取出右节点
if(node.right != null) {
deque.addFirst(node.right);
}
if(node.left != null) {
deque.addFirst(node.left);
}
list.add(node.val);
}
ret.add(list);
}
return ret;
}
}
思路3:递归
递归记录当前层数,存入对应的列表中
public class Solution {
public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
dfs(0, pRoot);
return ret;
}
ArrayList<ArrayList<Integer>> ret = new ArrayList<>();
void dfs(int level, TreeNode node) {
if(node == null) {
return;
}
if(ret.size() == level) {
ret.add(new ArrayList<>());
}
if(level % 2 == 1) {
ret.get(level).add(0, node.val);
} else {
ret.get(level).add(node.val);
}
dfs(level + 1, node.left);
dfs(level + 1, node.right);
}
}