描述
给定一个二叉树,返回该二叉树的之字形层序遍历,(第一层从左向右,下一层从右向左,一直这样交替)
数据范围:0≤n≤15000≤n≤1500,树上每个节点的val满足 ∣val∣<=100∣val∣<=100
要求:空间复杂度:O(n)O(n),时间复杂度:O(n)O(n)
例如:
给定的二叉树是{1,2,3,#,#,4,5}
该二叉树之字形层序遍历的结果是
[
[1],
[3,2],
[4,5]
]
示例1
输入:{1,2,3,#,#,4,5}
返回值:[[1],[3,2],[4,5]]
说明:如题面解释,第一层是根节点,从左到右打印结果,第二层从右到左,第三层从左到右。
示例2
输入:{8,6,10,5,7,9,11}
返回值:[[8],[10,6],[5,7,9,11]]
示例3
输入:{1,2,3,4,5}
返回值:[[1],[3,2],[4,5]]
思路: 队列+层序遍历
层次遍历打印二叉树,用队列实现。 有一句话,我觉得说的特别好:做题=解法+模板,意思就是说,对于一道题目,首先明白正确的解法已经解决该问题70%,剩下的就直接套模板。
所以BFS的模板为:
- 如果不需要确定当前遍历到了哪一层,模板如下:
void bfs() {
vis[] = {0}; // or set
queue<int> pq(start_val);
while (!pq.empty()) {
int cur = pq.front(); pq.pop();
for (遍历cur所有的相邻节点nex) {
if (nex节点有效 && vis[nex]==0){
vis[nex] = 1;
pq.push(nex)
}
} // end for
} // end while
}
上述是伪代码,不仅可用于二叉树,可针对所有用BFS解题。
- 如果需要确定遍历到哪一层,模板如下:
void bfs() {
int level = 0;
vis[] = {0}; // or set
queue<int> pq(original_val);
while (!pq.empty()) {
int sz = pq.size();
while (sz--) {
int cur = pq.front(); pq.pop();
for (遍历cur所有的相邻节点nex) {
if (nex节点有效 && vis[nex] == 0) {
vis[nex] = 1;
pq.push(nex)
}
} // end for
} // end inner while
level++;
} // end outer while
}
此题跟“按层打印二叉树”,仅有一点区别,“按层打印二叉树”是每层都按照从左到右打印二叉树。 而此题是,按照奇数层,从左到右打印,偶数层,从右到左打印。 所以此题可直接套用模板,代码如下:
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
vector<vector<int> > Print(TreeNode* pRoot) {
vector<vector<int>> res;
queue<TreeNode*> que;
if(pRoot == nullptr) return res;
que.push(pRoot);
int num = 0;
while(!que.empty())
{
int len = que.size();
vector<int> vec;
num++;
for(int i = 0;i < len; i++)
{
auto node = que.front();
que.pop();
vec.push_back(node->val);
if(node->left)
{
que.push(node->left);
}
if(node->right)
{
que.push(node->right);
}
}
if(num % 2 == 0)
{
reverse(vec.begin(), vec.end());
}
res.push_back(vec);
}
return res;
}
};