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; } };