二叉树的Z字形层次遍历 binary-tree-zigzag-level-order-traversal
题目描述
Given a binary tree, return the zigzag level ordertraversal of its nodes’ values. (ie, from left to right, then right to left for the next level and alternate between).
For example:
Given binary tree{3,9,20,#,#,15,7},
return its zigzag level order traversal as:
[
[3],
[20,9],
[15,7]
]
解题思路
- 在层次遍历的基础上,设置level记录当前层号(从1开始)
- 用cur数组保存每一层的节点数
- 如果level为奇数层,则直接将cur保存进结果
- 如果level为偶数层,则先将cur翻转,再存进结果
/**
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
class Solution {
public:
vector<vector<int> > zigzagLevelOrder(TreeNode* root) {
vector<vector<int> > res;
if(root == NULL) return res;
queue<TreeNode*> myque;
myque.push(root);
//奇数层从左往右,偶数层从右往左
int level(1);
while(!myque.empty()) {
int size = myque.size(); //每一层节点数
vector<int> cur; //保存当前层节点
for(int i = 0; i < size; i ++) {
TreeNode* temp = myque.front();
myque.pop();
cur.push_back(temp -> val);
if(temp -> left) myque.push(temp -> left);
if(temp -> right) myque.push(temp -> right);
}
//如果是偶数层,需要翻转cur数组
if(!(level & 0x01)) {
reverse(cur.begin(), cur.end());
}
level ++; //层次加一
res.push_back(cur); //将当前层添加进结果
}
return res;
}
};
- 改进:不进行翻转,而是在对每一层操作时,利用deque双端队列的进队、出队上进行修改,从而实现翻转的目的。
- deque双端队列的用法:
dq.push_back(a)
:在尾部插入元素adq.push_front(a)
:在头部插入元素adq.pop_back()
:弹出尾元素dq.pop_front()
:弹出头元素dq.front()
:取出头元素dq.back()
:取出尾元素
/**
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
class Solution {
public:
vector<vector<int> > zigzagLevelOrder(TreeNode* root) {
vector<vector<int> > res;
if(root == NULL) return res;
deque<TreeNode*> myque;
myque.push_back(root);
//奇数层从左往右,偶数层从右往左
int level(1);
while(!myque.empty()) {
int size = myque.size(); //每一层节点数
vector<int> cur; //保存当前层节点
for(int i = 0; i < size; i ++) {
//如果是奇数层,则按照常规层次遍历来
if(level & 0x01) {
//前端弹出
TreeNode* temp = myque.front();
myque.pop_front();
cur.push_back(temp -> val);
//后端插入
if(temp -> left) myque.push_back(temp -> left);
if(temp -> right) myque.push_back(temp -> right);
} else {
//如果是偶数层,则利用deque的特性实现翻转的目的,从后往前遍历
//后端弹出
TreeNode* temp = myque.back();
myque.pop_back();
cur.push_back(temp -> val);
//前端插入
if(temp -> right) myque.push_front(temp -> right);
if(temp -> left) myque.push_front(temp -> left);
}
}
level ++; //层次加一
res.push_back(cur); //将当前层添加进结果
}
return res;
}
};