题目描述
给定一个二叉树,返回其节点值的锯齿形层序遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。
例如: 给定二叉树 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回锯齿形层序遍历如下:
[
[3],
[20,9],
[15,7]
]
思路
很明显这题在层序遍历的基础上加以改动即可AC。对于常规的层序遍历,我们使用数据结构 队列 可始终从左到右(或从右到左)遍历每一层。对于锯齿形层序遍历(之字形层序遍历)我们在遍历完一层后要改变遍历的方向,按照左至右->右至左->左至右...这样的顺序不断进行下去,直至遍历完每一层。
针对这样的问题,我们使用双端队列这一数据结构双端都可访问的性质;并依据顺序遍历顺序插,倒序遍历倒序插这一原则不断进行下去,直至遍历完每一层。
- 示例 给定二叉树:[3,9,20,null,null,15,7]
//首先将根节点入队
deque.push_back(3);
//顺序遍历顺序插,将当前层的所有元素从双端队列的头出队,将它们的左孩子与右孩子按顺序插至双端队列尾部
deque.pop_front();//3出队
deque.push_back(9);
deque.push_back(20);
//倒序遍历倒序插,将当前层的所有元素从双端队列的尾出队,将它们的右孩子与左孩子按倒序插至双端队列头部
deque.pop_back();//20出队
deque.push_front(7);
deque.push_front(15);
deque.pop_back();//9出队
//顺序遍历顺序插,将当前层的所有元素从双端队列的头出队,将它们的左孩子与右孩子按顺序插至双端队列尾部
deque.pop_front();//15出队
deque.pop_front();//7出队
//队列空,遍历结束
C++代码
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
if(!root)
return res;
//利用双端队列两端都可访问的性质
deque<TreeNode*> dq;
dq.push_back(root);
int flag = -1;
while(!dq.empty()){
int len = dq.size();
res.push_back(vector<int>());
if(flag < 0){
//顺序遍历顺序插
for(int i = 0; i < len; i ++ ){
TreeNode *node = dq.front();
dq.pop_front();
res.back().push_back(node->val);
if(node->left)
dq.push_back(node->left);
if(node->right)
dq.push_back(node->right);
}
}
else{
//倒序遍历倒序插
for(int i = 0; i < len; i ++ ){
TreeNode *node = dq.back();
dq.pop_back();
res.back().push_back(node->val);
if(node->right)
dq.push_front(node->right);
if(node->left)
dq.push_front(node->left);
}
}
flag *= -1;
}
return res;
}
};
本文正在参与「掘金 3 月闯关活动」,点击查看活动详情。