文章目录
打印二叉树 I:借助队列层序遍历:时间O(n),空间O(n)
时间:遍历二叉树需要O(n)的时间
空间:当为平衡二叉树时,当打印最后一层时,最多有 (n+1)/2 个节点,也就是O(n)的空间复杂度
题解:
- 队列初始化插入根节点
- 出队,把当前节点的值插入数组,如果节点左树不空则入队,右树不空则入队
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> levelOrder(TreeNode* root)
{
// 层序遍历:借助队列
vector<int> res;
if (root == nullptr)
return res;
queue<TreeNode*> que;
que.push(root);
while (!que.empty())
{
TreeNode* node = que.front();
que.pop();
res.push_back(node->val);
if (node->left)
que.push(node->left);
if (node->right)
que.push(node->right);
}
return res;
}
};
打印二叉树 II:借助队列并记录每次个数:时间O(n),空间O(n)
时间:遍历二叉树需要O(n)的时间
空间:当为平衡二叉树时,当打印最后一层时,最多有 (n+1)/2 个节点,也就是O(n)的空间复杂度
题解:
- 队列初始化插入根节点
- 出队,把当前节点的值插入数组,如果节点左树不空则入队,右树不空则入队
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root)
{
vector<vector<int>> ans;
if (root == nullptr)
return ans;
queue<TreeNode*> que;
que.push(root);
while (!que.empty())
{
int n = que.size();
vector<int> vec;
while (n--)
{
TreeNode* node = que.front();
que.pop();
vec.push_back(node->val);
if (node->left)
que.push(node->left);
if (node->right)
que.push(node->right);
}
ans.push_back(vec);
}
return ans;
}
};
打印二叉树 III:
方法一:双端队列一次打印两层,时间O(n),空间O(n)
时间:遍历二叉树需要O(n)的时间
空间:当为平衡二叉树时,当打印最后一层时,最多有 (n+1)/2 个节点,也就是O(n)的空间复杂度
题解:
- 利用双端队列的特性,一个循环打印两层元素
- 偶数层:双端队列左端出队,右端插入。先插入每个节点的左树再插入右树
- 奇数层:双端队列右端出队,左端插入。先插入每个节点的右树再插入左树
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root)
{
// 1.双端队列,一次性打印两层数据
vector<vector<int>> ans;
if (root == nullptr)
return ans;
deque<TreeNode*> que;
que.push_back(root);
while (!que.empty())
{
vector<int> vec;
int n = que.size();
while (n--) // 打印偶数层,从前出队列,并且插入队列末尾
{
TreeNode* node = que.front();
que.pop_front();
vec.push_back(node->val);
if (node->left)
que.push_back(node->left); // 先插左树再插右树
if (node->right)
que.push_back(node->right);
}
ans.push_back(vec);
if (que.empty())
break;
n = que.size();
vec.clear();
while (n--) // 打印奇数层,从后出队列,并且插入队列首部
{
TreeNode* node = que.back();
que.pop_back();
vec.push_back(node->val);
if (node->right)
que.push_front(node->right); // 先插右树再插左树
if (node->left)
que.push_front(node->left);
}
ans.push_back(vec);
}
return ans;
}
};
方法二:队列,对奇数层进行反转
题解:
- 队列操作和题二一样,新增一个标志位,当遇到奇数位时,反转数组
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root)
{
// 2.普通队列,如果是奇数层则进行反转数据
vector<vector<int>> ans;
if (root == nullptr)
return ans;
queue<TreeNode*> que;
que.push(root);
int flag = 0; // 标志位
while (!que.empty())
{
int n = que.size();
vector<int> vec;
while (n--)
{
TreeNode* 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 (flag) // 如果时奇数层则反转数组
reverse(vec.begin(), vec.end());
flag ^= 1;
ans.push_back(vec);
}
return ans;
}
};