1.思路:
层次遍历二叉树,其中用变量size来确定每一层中结点的个数,定义bool变量even来确定是第几层,若是偶数层,则将数组内的数进行颠倒,再存入二维数组中。
2.代码:
/*
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;
if(pRoot == NULL) return res;
queue<TreeNode*> q;
q.push(pRoot);
bool even = false;
while(!q.empty()) {
vector<int> tmpVector;
const int size = q.size(); //获取当前层结点的个数
for(int i = 0; i < size; ++i) {
TreeNode* tmpNode = q.front();
q.pop();
tmpVector.push_back(tmpNode->val);
if(tmpNode->left != NULL) {
q.push(tmpNode->left);
}
if(tmpNode->right != NULL) {
q.push(tmpNode->right);
}
}
if(even) {
int n = tmpVector.size();
vector<int> tmpVector2(n); //开辟新内存,颠倒数组
for(int i = 0; i < n; ++i) {
tmpVector2[i] = tmpVector[n - 1 - i];
}
res.push_back(tmpVector2);
} else {
res.push_back(tmpVector);
}
even = !even;
}
return res;
}
};
二刷代码,改进了空间复杂度,采用自定义的ReverseArr函数,对原数组进行颠倒,代码如下:
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
void ReverseArr(vector<int> &arr) {
int tmp;
int num = arr.size();
for(int i = 0; i < num/2; ++i) {
tmp = arr[i];
arr[i] = arr[num-i-1];
arr[num-i-1] = tmp;
}
}
vector<vector<int> > Print(TreeNode* pRoot) {
vector<vector<int>> res;
if(pRoot == NULL) return res;
bool l2r = true;
queue<TreeNode*> q;
q.push(pRoot);
while(!q.empty()) {
vector<int> tmpRaw;
TreeNode *tmpNode;
int total = q.size();
for(int i = 0; i < total; ++i) {
tmpNode = q.front();
q.pop();
if(tmpNode->left != NULL) q.push(tmpNode->left);
if(tmpNode->right != NULL) q.push(tmpNode->right);
tmpRaw.push_back(tmpNode->val);
}
if(l2r) {
res.push_back(tmpRaw);
} else {
ReverseArr(tmpRaw);
res.push_back(tmpRaw);
}
l2r = !l2r;
}
return res;
}
};
二刷思路二:
采用两个栈来解决,其中s[0]栈用来存放当前需要打印的结点,s[1]栈用来保存下一次需要打印的结点,开始时s[0]存入根节点,s[1]入栈按照从左孩子结点到右孩子结点,这样出栈再打印就是从右往左;在s[0]为空时,将数组存入res中,并令s[0]与s[1]进行交换,s[1]出栈打印,并按照从右孩子到左孩子的顺序,入栈s[0],这样出栈时就又变成了从左往右打印结点。如此往复,直到s[0]与s[1]同时为空,此时返回res即为最终结果。该方法利用栈的特性,省去了方法一中倒转数组的步骤,更佳!
代码二:
/*
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;
if(pRoot == NULL) return res;
stack<TreeNode*> s[2];
int cur = 0;
int next = 1;
s[cur].push(pRoot);
vector<int> tmp;
while(!s[0].empty() || !s[1].empty()) {
TreeNode* tmpNode = s[cur].top();
s[cur].pop();
tmp.push_back(tmpNode->val);
if(cur == 0) {
if(tmpNode->left != NULL) s[next].push(tmpNode->left); //从左往右入栈
if(tmpNode->right != NULL) s[next].push(tmpNode->right);
} else {
if(tmpNode->right != NULL) s[next].push(tmpNode->right); //从右往左入栈
if(tmpNode->left != NULL) s[next].push(tmpNode->left);
}
if(s[cur].empty()) { //单行打印完,将tmp传入res中,并更新tmp数组和cur、next的数值
res.push_back(tmp);
tmp.clear();
cur = 1 - cur;
next = 1 - next;
}
}
return res;
}
};