1.层序遍历(10道题)
力扣题目链接 102.二叉树的层序遍历
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
queue<TreeNode*> que;
vector<vector<int>> result;
// 初始化
if(root != NULL) que.push(root);
// 当队列不为空时,将队列中的元素弹出加入数组,并将此元素的左右孩子加入队列
while(!que.empty()){
// 用size记录每层的结点数量
int size = que.size();
vector<int> nums;
// 对该层的元素做处理,同时加入下一层的结点
while(size--){
TreeNode* node = que.front();
que.pop();
nums.push_back(node->val);
if(node->left != NULL) que.push(node->left);
if(node->right != NULL) que.push(node->right);
}
result.push_back(nums);
}
return result;
}
};
力扣题目链接 107层序遍历2
class Solution {
public:
vector<vector<int>> levelOrderBottom(TreeNode* root) {
queue<TreeNode*> que;
vector<vector<int>> result;
if(root != NULL) que.push(root);
while(!que.empty()){
int size = que.size();
vector<int> vec;
while(size--){
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二叉树的右视图
class Solution {
public:
vector<int> rightSideView(TreeNode* root) {
queue<TreeNode*> que;
vector<int> result;
if(root != NULL) que.push(root);
while(!que.empty()){
int size = que.size();
while(size--){
TreeNode* node = que.front();
que.pop();
if(size == 0){
result.push_back(node->val);
}
if(node->left != NULL) que.push(node->left);
if(node->right != NULL) que.push(node->right);
}
}
return result;
}
};
易错点:我还是用了以前的while循环来解这道题,但是要注意循环里收集每层最右结点的条件判断应该让size和0比,因为进入循环时的size(循环判断时值为1)已经自减了,所以循环内(if判断)应该和0比。
力扣题目链接 637层平均值
class Solution {
public:
vector<double> averageOfLevels(TreeNode* root) {
vector<double> result;
queue<TreeNode*> que;
if(root != NULL) que.push(root);
while(!que.empty()){
int size = que.size();
int n = size;
double sum = 0;
while(size--){
TreeNode* node = que.front();
que.pop();
sum += node->val;
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
result.push_back(sum / n);
}
return result;
}
};
易错点:在第二次循环中,size的值已经被减为0,所以要用n来提前保存size的值。
力扣题目链接 429.N叉树的层序遍历
class Solution {
public:
vector<vector<int>> levelOrder(Node* root) {
vector<vector<int>> result;
queue<Node*> que;
if(root != NULL) que.push(root);
while(!que.empty()){
int size = que.size();
vector<int> vec;
while(size--){
Node* node = que.front();
que.pop();
vec.push_back(node->val);
for(int i = 0;i < node->children.size();i++){
if(node->children[i] != NULL) que.push(node->children[i]);
}
}
result.push_back(vec);
}
return result;
}
};
易错点:这里结点类型时Node,不要题也不看就TreeNode。还有定义的vec数组应该在第二层循环外,不然会丢失。
力扣题目链接515.在每个树行中找最大值
class Solution {
public:
vector<int> largestValues(TreeNode* root) {
vector<int> result;
queue<TreeNode*> que;
if(root != NULL) que.push(root);
while(!que.empty()){
int size = que.size();
int maxVal = INT_MIN;
while(size--){
TreeNode* node = que.front();
que.pop();
maxVal = maxVal > node->val? maxVal:node->val;
if(node->left != NULL) que.push(node->left);
if(node->right != NULL) que.push(node->right);
}
result.push_back(maxVal);
}
return result;
}
};
力扣题目链接116.填充每个节点的下一个右侧节点指针
class Solution {
public:
Node* connect(Node* root) {
queue<Node*> que;
if(root != NULL) que.push(root);
while(!que.empty()){
int size = que.size();
while(size--){
Node* node = que.front();
que.pop();
if(node->left != NULL) que.push(node->left);
if(node->right != NULL) que.push(node->right);
if(size != 0){
Node* node1 = que.front();
node->next = node1;
}else{
node->next = NULL;
}
}
}
return root;
}
};
力扣题目链接117.填充每个节点的下一个右侧节点指针II
queue<Node*> que;
if(root != NULL) que.push(root);
while(!que.empty()){
int size = que.size();
while(size--){
Node* node = que.front();
que.pop();
if(node->left != NULL) que.push(node->left);
if(node->right != NULL) que.push(node->right);
if(size != 0){
Node* node1 = que.front();
node->next = node1;
}else{
node->next = NULL;
}
}
}
return root;
力扣题目链接104.二叉树的最大深度
class Solution {
public:
int maxDepth(TreeNode* root) {
int n = 0;
queue<TreeNode*> que;
if(root != NULL) que.push(root);
while(!que.empty()){
n++;
int size = que.size();
while(size--){
TreeNode* node = que.front();
que.pop();
if(node->left != NULL) que.push(node->left);
if(node->right != NULL) que.push(node->right);
}
}
return n;
}
};
力扣题目链接111.二叉树的最小深度
class Solution {
public:
int minDepth(TreeNode* root) {
int n = 0;
if(root == NULL) return n;
queue<TreeNode*> que;
que.push(root);
while(!que.empty()){
n++;
int size = que.size();
while(size--){
TreeNode* node = que.front();
que.pop();
if(node->left==NULL && node->right==NULL){
return n;
}
if(node->left != NULL) que.push(node->left);
if(node->right != NULL) que.push(node->right);
}
}
return n;
}
};
2.翻转二叉树
题目链接/文章讲解/视频讲解: 代码随想录
递归法:前序遍历 (最好不要用中序遍历,会把已经翻转的结点又翻回去)
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if(root == NULL) return root;
// 前序遍历
swap(root->left,root->right);
invertTree(root->left);
invertTree(root->right);
return root;
}
};
层序遍历:
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if(root == NULL) return root;
queue<TreeNode*> que;
que.push(root);
while(!que.empty()){
int size = que.size();
while(size--){
TreeNode* node = que.front();
que.pop();
swap(node->left,node->right);
if(node->left != NULL) que.push(node->left);
if(node->right != NULL) que.push(node->right);
}
}
return root;
}
};
迭代法:前序遍历
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
stack<TreeNode*> st;
if(root != NULL) st.push(root);
while(!st.empty()){
TreeNode* node = st.top();
if(node != NULL){
st.pop(); // 为避免重复
// 前序遍历
// 右
if(node->right != NULL) st.push(node->right);
// 左
if(node->left != NULL) st.push(node->left);
// 中
st.push(node);
st.push(NULL);
}else{
st.pop(); // 把空结点弹出
node = st.top();
st.pop();
// 遍历操作
swap(node->left,node->right);
}
}
return root;
}
};
思路:其实就是遍历二叉树,翻转每个结点的左右孩子
3.对称二叉树
class Solution {
public:
bool comparision(TreeNode* left,TreeNode* right){
// 递归出口
if(left == NULL && right == NULL) return true;
else if(left == NULL && right != NULL) return false;
else if(left != NULL && right == NULL) return false;
else if(left->val != right->val) return false;
// 因为需要左右孩子的信息,本题只能用后序遍历
// 左
bool outside = comparision(left->left,right->right);
// 右
bool inside = comparision(left->right,right->left);
// 中
return outside&&inside;
}
bool isSymmetric(TreeNode* root) {
if(root == NULL) return true;
return comparision(root->left,root->right);
}
};
状态:把左右写对。
思路:就是同时遍历左右子树,看它们的外侧和内侧是否相等。