有两种解决途径,但是规律类似。
1.迭代实现
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
if (root != null) {
LinkedList<TreeNode> nodes = new LinkedList<>();
nodes.add(root);
boolean flag = true;//标记是奇数层还是偶数层
int lastCounts = 1;//用于记录上一层的节点数
while (lastCounts > 0) {
LinkedList<Integer> list = new LinkedList<>();
int counts = lastCounts;
lastCounts = 0;
for (int i = 0; i < counts; i++) {
// 每次都是从队列取第一个节点元素
TreeNode node = nodes.poll();
//从左往右
if (flag) {
// 先遍历到的节点要在下一个的后面
// 即后遍历到的排在最前面
list.addFirst(node.val);
} else {
list.addLast(node.val);
}
// 每次都后将节点添加到队列的最后
if (node.right!=null) {
nodes.offer(node.right);
lastCounts++;
}
if (node.left!=null) {
nodes.offer(node.left);
lastCounts++;
}
}
result.add(list);
flag = !flag;
}
}
return result;
}
因为每次都是先在队列里面添加右子节点,因此在遍历每一层的时候,实际上总是从每一层的最右边开始,然后动态的改变浏览的元素值的添加方向即可,这样实现起来比较简单直观。
2.递归实现
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
tmp(0, result, root);
return result;
}
/**
* @param level 用户记录遍历的层级
*/
public void tmp(int level,List<List<Integer>> result,TreeNode node) {
if (node==null) return;
LinkedList<Integer> list;
if (level >= result.size()) {
list = new LinkedList<>();
result.add(list);
} else {
list = (LinkedList<Integer>) result.get(level);
}
if (level % 2 == 0) {
list.addFirst(node.val);
} else {
list.addLast(node.val);
}
//每次都是先递归遍历右子节点
//从保持每一层的遍历都是先从最右边开始
tmp(level+1, result, node.right);
tmp(level+1, result, node.left);
}
递归的实现思想大致与迭代的一样。