LeetCode 102 二叉树的层序遍历
题目链接:102. 二叉树的层序遍历
做题情况:独立做本题目的时候,知道用队列来实现,如果直接把所有结果放在一个数组里面,自己能够写出来,但是本题每一层的元素放在不同的数组里面,最后组成一个二维数组,这就要求我们还要记录层数,也就是每层所有元素个数,当时自己没有想出来咋样做,看完卡哥视频和代码随想录书相关部分后,才知道也很简单,只需要一个size变量来记录每一层个数大小然后循环遍历记录即可,特别注意不能用que.size()直接来求,队列的长度是不断变化的,具体代码如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>>result;
queue<TreeNode*>que;
if(root==nullptr)return result;
que.push(root);
while(!que.empty()){
int size=que.size();//记录每一层元素个数大小,来把每一层元素放进不同的数组里面
vector<int>vec;
for(int i=0;i<size;i++){
TreeNode* tmp=que.front();
que.pop();
vec.push_back(tmp->val);
if(tmp->left)que.push(tmp->left);
if(tmp->right)que.push(tmp->right);
}
result.push_back(vec);
}
return result;
}
};
本题目层序遍历结合具体实例更容易理解和写出代码,本题目也可以通过递归法来实现层序遍历,具体如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
void order(TreeNode* cur, vector<vector<int>>&result, int depth){
if(cur==nullptr)return;
if(result.size()==depth)result.push_back(vector<int>());
result[depth].push_back(cur->val);
order(cur->left, result, depth+1);
order(cur->right, result, depth+1);
}
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>>result;
int depth=0;
order(root, result, depth);
return result;
}
};
LeetCode 226 翻转二叉树
题目链接:226. 翻转二叉树
做题情况:自己虽然是二刷代码随想录,但是看到这道题目还是很懵逼,自己现在还是没有克服写递归算法的恐惧,觉得这些都很复杂,后面得慢慢练习和提高,看完卡哥视频和代码随想录书相关部分后,才知道把每一个节点得左右孩子交换一下即可,这时候就要确定遍历顺序即可,在本题目中前序和后序都可以,如果使用中序遍历的话就需要防止某些节点的左右孩子翻转了两次,这些所有都可以结合图形实例来理解,在这里重点给出前序遍历的代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
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;
}
};
递归的写法都可以用前面所学的普通迭代写法和统一迭代写法来完成,,不过要注意中序遍历迭代写法和递归写法的区别,具体前序遍历代码如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
//普通迭代写法
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if(root==NULL)return root;
stack<TreeNode*>st;
st.push(root);
while(!st.empty()){
TreeNode* node=st.top();
st.pop();
swap(node->left,node->right);
if(node->right)st.push(node->right);
if(node->left)st.push(node->left);
}
return root;
}
};
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
//统一迭代写法
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)st.push(node->right);
if(node->left) 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;
}
};
LeetCode 101 对称二叉树
题目链接:101. 对称二叉树
做题情况:和上题目一样,看到要用递归算法来解决问题自己就很蒙圈,看完卡哥视频和代码随想录书相关部分后,都并没有想象中的那么难,关键还是结合图形实例来写代码就不难了,牢记递归三部曲,这道题目实际上也是后序遍历的一个应用==(左子树左右中,右子树右左中)==,具体代码如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
bool compare(TreeNode* left, TreeNode* right){
if(left==NULL&&right!=NULL)return false;
else if(left!=NULL&&right==NULL)return false;
else if(left==NULL&&right==NULL)return true;
else if(left->val!=right->val)return false;
bool outside=compare(left->left, right->right);
bool inside=compare(left->right, right->left);
bool isSame=outside&&inside;
return isSame;
}
bool isSymmetric(TreeNode* root) {
if(root==NULL)return true;
return compare(root->left, root->right);
}
};
本题目也可以通过迭代写法来解决,不过不是上述递归写法来转变得迭代写法,而是把左右两个子树要比较的元素顺序放进一个容器,然后成对成对的取出来进行比较,这里面使用栈和队列数据结构均可以,下面是使用队列的代码,感觉这个迭代写法更容易理解,只是难以想到:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if(root==NULL)return true;
queue<TreeNode*>que;
que.push(root->left);
que.push(root->right);
while(!que.empty()){
TreeNode* leftNode=que.front();que.pop();
TreeNode* rightNode= que.front();que.pop();
if(!leftNode&&!rightNode){
continue;
}
if((!leftNode||!rightNode||(leftNode->val!=rightNode->val))){
return false;
}
que.push(leftNode->left);
que.push(rightNode->right);
que.push(leftNode->right);
que.push(rightNode->left);
}
return true;
}
};
今天所有的时间都花在后面两道题目的学习上,后面两道题目把卡哥的代码照着抄了一遍,还是无法克服写递归算法的恐惧感,后面要多多复习和独立思考完成,多自己去独立完成递归算法的书写,总共花了四个小时左右。
贵在坚持,加油,共勉