11、二叉树的锯齿形层序遍历
题目
给定一个二叉树,返回其节点值的锯齿形层序遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。
例如:
给定二叉树 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \ / \
nn 15 7
返回锯齿形层序遍历如下:
[
[3],
[20,9],
[15,7]
]
11.0、一般解法
正常的层序遍历,然后如果是偶数层的话就反转一下数组,非暴力不合作。
vector<vector<int>> zigzagLevelOrder0(TreeNode* root)
{
vector<vector<int>> result;
if (!root)return result; //头节点为空直接返回
queue<TreeNode*> data;
data.push(root);
bool flag = false; //代表方向
while (!data.empty())
{
int size = data.size();
vector<int> resPart;
for (int i = 0; i < size; i++)
{
TreeNode* tempNode = data.front();
data.pop();
if (tempNode->left)data.push(tempNode->left);
if (tempNode->right)data.push(tempNode->right);
resPart.push_back(tempNode->val);
}
if (flag)reverse(resPart.begin(), resPart.end());
flag = !flag;
result.push_back(resPart);
}
return result;
}
- 时间复杂度:O(n)n为节点数
- 空间复杂度:O(n)n为最大层节点数,不考虑结果占用的空间
11.1、双端队列
说实话,在这道题之前,博主从来都没有用过双端队列(-_-)
这个题解是看别人的
在上面的方法中,把每一层的数值直接放到结果集中,然后根据奇偶来对结果集进行翻转
在这里,根据奇偶层把数值插入到双端队列的头或尾,然后再赋值到结果集中,实际上多使用了空间,而且性能和上面基本一样。
但是,这种方法更切合题意,那就是层序遍历(虽然有点牵强)。
vector<vector<int>> zigzagLevelOrder1(TreeNode* root)
{
vector<vector<int>> result;
if (!root)return result; //头节点为空直接返回
queue<TreeNode*> data;
data.push(root);
bool flag = true; //代表方向
while (!data.empty())
{
deque<int> tempResPart;
int size = data.size();
for (int i = 0; i < size; i++)
{
TreeNode* tempNode = data.front();
data.pop();
if (tempNode->left)data.push(tempNode->left);
if (tempNode->right)data.push(tempNode->right);
if (flag)
tempResPart.push_back(tempNode->val);
else
tempResPart.push_front(tempNode->val);
}
flag = !flag;
result.push_back(vector<int>{tempResPart.begin(), tempResPart.end()});//这种写法还没见过
}
return result;
}
- 时间复杂度:O(n)n为节点数
- 空间复杂度:O(n)n为最大层节点数(实际上应该为2 n),不考虑结果占用的空间