题目链接:226. 翻转二叉树 - 力扣(LeetCode)
class Solution
{
public:
TreeNode *invertTree(TreeNode *root)
{
queue<TreeNode *> que;
if (root)
que.push(root);
while (!que.empty())
{
int size = que.size();
for (int i = 0; i < size; i++)
{
TreeNode *node = que.front();
que.pop();
TreeNode *tmp;
tmp = node->right;
node->right = node->left;
node->left=tmp;
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
}
return root;
}
};
思路
第一个想法就是一层层遍历,一层层交换次序
解题方法
使用队列辅助的层序遍历,每到一层就交换一次左右结点,一直遍历下去。
我们先把根节点入队列,然后进入循环进行操作。
循环的次数为n次,n是当前层的结点数。-->出队列的同时把该节点的左右子节点入队列。这个操作一直执行到循环结束。
这样子做有什么作用呢,细想一下,队列有先进先出的特性,我们操作n次,保证把这一层所有结点都出了队列,同时又把下一层所有节点入了队列(因为我们出队列的同时把其左右叶子加入了队列)。
如此,我们就完成了广度优先遍历。
然后,我们只需要在每次添加结点入队列的时候,调换一下左右节点就行。
复杂度
时间复杂度:
O(n)
空间复杂度:
O(n)
题目链接:101. 对称二叉树 - 力扣(LeetCode)
class Solution
{
public:
bool compare(TreeNode *left, TreeNode *right)
{
// 首先排除空结点的情况
if (left == nullptr && right != nullptr)
return false;
else if (left != nullptr && right == nullptr)
return false;
else if (left == nullptr && right == nullptr)
return true;
// 排除了空结点,再排除值不相等
else if (left->val != right->val)
return false;
//此时的情况是左右节点都不为空并且值都相等
//此时才做递归,做下一层的判断
bool outside=compare(left->left,right->right);
bool inside=compare(left->right,right->left);
return outside&&inside;
}
bool isSymmetric(TreeNode *root)
{
if (root == nullptr)
return true;
return compare(root->left, root->right);
}
};
思路
比较左右外层和内层是否相等即可
解题方法
可以使用队列或者栈进行辅助的迭代法,将内外层分别装进去再进行操作。这里使用递归法来解决。原理是利用递归一层层的走下去,保证每次判断两边都是外层或内层。
复杂度
时间复杂度:
O(n)
空间复杂度:
O(n)
以下是广度优先十道题
题目链接:102. 二叉树的层序遍历 - 力扣(LeetCode)
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
queue<TreeNode *> que;
vector<vector<int>> result;
if (root)
que.push(root);
while (!que.empty())
{
int size = que.size();
vector<int> vec;
for (int i = 0; i < size; i++)
{
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);
}
result.push_back(vec);
}
return result;
}
};
题目链接:107. 二叉树的层序遍历 II - 力扣(LeetCode)
class Solution {
public:
vector<vector<int>> levelOrderBottom(TreeNode* root) {
queue<TreeNode *> que;
vector<vector<int>> result;
if (root)
que.push(root);
while (!que.empty())
{
int size = que.size();
vector<int> vec;
for (int i = 0; i < size; i++)
{
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);
}
result.push_back(vec);
}
reverse(result.begin(),result.end());
return result;
}
};
题目链接:199. 二叉树的右视图 - 力扣(LeetCode)
class Solution {
public:
vector<int> rightSideView(TreeNode* root) {
queue<TreeNode*> que;
if (root != NULL) que.push(root);
vector<int> result;
while (!que.empty()) {
int size = que.size();
for (int i = 0; i < size; i++) {
TreeNode* node = que.front();
que.pop();
if (i == (size - 1)) result.push_back(node->val); // 将每一层的最后元素放入result数组中
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
}
}
return result;
}
};
思路
本质上还是用层序遍历来遍历每一层
解题方法
做这道题前先要搞清楚右视图是什么。简而言之就是从右边看过去,每一层都只能看到一个结点。这时候要思考的就来了,如果右子树有东西,那我们自然看到的就是右子树上的结点。那么如果右子树没东西呢?我们当然看到的就是左子树上面的结点,所以在解题的时候不能只考虑右子树上的结点,也要看左子树。
那这么说这道题岂不是很麻烦?
非也,仔细想想,其实我们并不用分左右讨论,我们要在意的,只有每一层最后一个结点就行,这个结点,就是我们从右视图看到的结点。
复杂度
时间复杂度:
O(n)
空间复杂度:
O(n)
题目链接:637. 二叉树的层平均值 - 力扣(LeetCode)
class Solution {
public:
vector<double> averageOfLevels(TreeNode* root) {
queue<TreeNode *> que;
vector<double> result;
if (root)
que.push(root);
while (!que.empty())
{
int size = que.size();
long cnt=0;
for (int i = 0; i < size; i++)
{
TreeNode *node = que.front();
que.pop();
cnt+=node->val;
if (node->left)
que.push(node->left);
if (node->right)
que.push(node->right);
}
result.push_back(cnt*1.0/size);
cnt=0;
}
return result;
}
};
题目链接:429. N 叉树的层序遍历 - 力扣(LeetCode)
class Solution {
public:
vector<vector<int>> levelOrder(Node* root) {
queue<Node*> que;
vector<vector<int>> result;
if(root) que.push(root);
while(!que.empty()){
int size=que.size();
vector<int> vec;
for(int i=0;i<size;i++){
Node* node=que.front();
que.pop();
vec.push_back(node->val);
for(Node *tmp:node->children){
if(tmp) que.push(tmp);
}
}
result.push_back(vec);
}
return result;
}
};
思路
本质上和二叉树层序遍历一样
解题方法
利用队列先进先出的特性,先把根节点入队列。然后进行操作n次,n为本层的结点数------->出队列的同时把本结点全部子节点入队。
这样子保证了把本层所有结点都出了队列,同时把下一层所有结点入队列。
这就是层序遍历的基本思想。
复杂度
时间复杂度:
O(n)
空间复杂度:
O(n)
题目链接:515. 在每个树行中找最大值 - 力扣(LeetCode)
class Solution {
public:
vector<int> largestValues(TreeNode* root) {
queue<TreeNode *> que;
vector<int> result;
if (root)
que.push(root);
while (!que.empty())
{
int size = que.size();
int max=que.front()->val;
for (int i = 0; i < size; i++)
{
TreeNode *node = que.front();
que.pop();
if(node->val>max) max=node->val;
if (node->left)
que.push(node->left);
if (node->right)
que.push(node->right);
}
result.push_back(max);
}
return result;
}
};
题目链接:116. 填充每个节点的下一个右侧节点指针 - 力扣(LeetCode)
class Solution {
public:
Node* connect(Node* root) {
queue<Node *> que;
if (root)
que.push(root);
while (!que.empty())
{
int size = que.size();
Node *leftNode;
Node *node;
for (int i = 0; i < size; i++)
{
if(i==0){
leftNode=que.front();
que.pop();
node=leftNode;
}else{
node=que.front();
que.pop();
leftNode->next=node;
leftNode=leftNode->next;
}
if (node->left)
que.push(node->left);
if (node->right)
que.push(node->right);
}
}
return root;
}
};
题目链接:117. 填充每个节点的下一个右侧节点指针 II - 力扣(LeetCode)
class Solution {
public:
Node* connect(Node* root) {
queue<Node *> que;
if (root)
que.push(root);
while (!que.empty())
{
int size = que.size();
Node *leftNode;
Node *node;
for (int i = 0; i < size; i++)
{
if(i==0){
leftNode=que.front();
que.pop();
node=leftNode;
}else{
node=que.front();
que.pop();
leftNode->next=node;
leftNode=leftNode->next;
}
if (node->left)
que.push(node->left);
if (node->right)
que.push(node->right);
}
}
return root;
}
};
题目链接:104. 二叉树的最大深度 - 力扣(LeetCode)
class Solution {
public:
int maxDepth(TreeNode* root) {
queue<TreeNode *> que;
if(root) que.push(root);
int depth=0;
while(!que.empty()){
int size=que.size();
depth++;
for(int i=0;i<size;i++){
TreeNode *node=que.front();
que.pop();
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
}
return depth;
}
};
题目链接:111. 二叉树的最小深度 - 力扣(LeetCode)
class Solution {
public:
int minDepth(TreeNode* root) {
queue<TreeNode *> que;
if(root) que.push(root);
int depth=0;
while(!que.empty()){
int size=que.size();
depth++;
for(int i=0;i<size;i++){
TreeNode *node=que.front();
que.pop();
if(!node->left&&!node->right) return depth;
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
}
return depth;
}
};