算法
(BFS) $O(n)$
层次遍历,可以运用 BFS
的思想实现从上往下的逐层遍历。从头结点开始逐层遍历,开辟一个新队列,让头结点入队并计算此时的长度,每次都将当前层的子节点全部压入队列,然后对下一层的节点进行遍历,再将下一层的子节点压入队列,不断循环,一直遍历到底层,判断的终止条件就是队列不为空。
- 循环里面,队列头出队,判断其是否有左右子结点,如果有,则将此点的子节点入队,但此时还不需要更新队列的长度,当前队列的长度是每层的长度。当这层的长度减为0时,就说明这层的遍历结束,开始更新长度为下一层的长度
- 出队的元素的值按照一层层压入结果数组
- 因为题目锯齿形遍历
- 我们用一个
isforward
标记当前方向,每遍历完一层,如果是反向的,则将这层的节点数组倒序,然后将这层的集合压入结果
C++ 代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
vector<vector<int>> ans;
if (root == NULL) {
return ans;
}
queue<TreeNode*> q;
//正反向标志
bool isForward = true;
q.push(root);
while (!q.empty()) {
int len = q.size();
vector<int> tmplist;
for (int i = 0;i < len;i++) {
TreeNode *treeNode = q.front();
q.pop();
tmplist.push_back(treeNode -> val);
if (treeNode -> left != NULL) {
q.push(treeNode -> left);
}
if (treeNode -> right != NULL) {
q.push(treeNode -> right);
}
}
//根据标志来确认当前层遍历的方向
if (!isForward) {
reverse(tmplist.begin(),tmplist.end());//翻转
}
ans.push_back(tmplist);
//方向反转
isForward=!isForward;
}
return ans;
}
};
Java 代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList();
if (root == null) return res;
Queue<TreeNode> queue = new LinkedList();
queue.add(root);
boolean isRev = false;
while (!queue.isEmpty()) {
int size = queue.size();
List<Integer> level = new ArrayList();
for (int i = 0; i < size; ++i) {
TreeNode cur = queue.remove();
level.add(cur.val);
if (cur.left != null) queue.add(cur.left);
if (cur.right != null) queue.add(cur.right);
}
if (isRev) Collections.reverse(level);
isRev = !isRev;
res.add(new ArrayList(level));
}
return res;
}
}