题目:层序遍历、226.翻转二叉树、101. 对称二叉树
参考链接:代码随想录
层序遍历
102.二叉树的层序遍历
107.二叉树的层次遍历II
199.二叉树的右视图
637.二叉树的层平均值
429.N叉树的层序遍历
515.在每个树行中找最大值
116.填充每个节点的下一个右侧节点指针
117.填充每个节点的下一个右侧节点指针II
104.二叉树的最大深度
111.二叉树的最小深度
思路:层序遍历就是BFS,即一层一层遍历。需要使用一个queue,首先将根节点入队,如果队列不为空,则出队。如果队头存在孩子,则将其左右孩子入队,依次类推。
但我在代码实现的时候虽然能够完成遍历,但没想到如何将每一层的所有元素放到一个vector中,看标答后才发现需要记录队列长度即可,即为每一层的长度。时间复杂度O(n),遍历都是O(n)。
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
queue<TreeNode*> q;
vector<vector<int>> ans;
if(root){
q.push(root);
}
while(!q.empty()){
int size=q.size();
vector<int> tmp={};
for(int i=0;i<size;i++){
if(q.front()->left){
q.push(q.front()->left);
}
if(q.front()->right){
q.push(q.front()->right);
}
tmp.push_back(q.front()->val);
q.pop();
}
ans.push_back(tmp);
}
return ans;
}
};
递归算法没细看,感觉不是很实用,空间复杂度也高,对BFS主要是掌握队列使用。
其他剩余题目都不难,思路都类似。
每行找最大值那题可以直接定义max=INT_MIN,在每层遍历的时候就比较,不需要再单独定义一个函数。
最小深度不需要全部遍历完,找到第一个叶子节点的深度必定最小,可以直接返回。
226.翻转二叉树
思路:递归思想,先考虑根节点,递归返回条件即为根节点为空,或者其左右孩子都为空,然后正常递归即可。时间复杂度O(n)。
class Solution {
public:
void invTree(TreeNode* root){
if(!root||(!root->left&&!root->right)){//自己为空或者左右节点都为空则不需要操作
return;
}
else{
swap(root->left,root->right);
invTree(root->left);
invTree(root->right);
}
}
TreeNode* invertTree(TreeNode* root) {
invTree(root);
return root;
}
};
看完标答发现前序后序遍历都可以,我进行的是前序遍历,所以可以不加左右节点都不为空的那个判断。然后还可以使用迭代法写。
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
stack<TreeNode*> st;
if(!root){
return nullptr;
}
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;
}
};
101. 对称二叉树
思路:本题想了很久没找到思路,主要不知道如何遍历能比较两个子树是否对称。看了解析需要将对比两边子树单独写成一个函数,比较子树对称的时候,需要比较其外侧子树是否对称,还有其内侧子树是否对称。对于结束条件,要想清楚空指针的情况,如果要比较的两个节点两个为空则对称,一个为空一个不为空则不对称,两个都不为空则正常比较。
class Solution {
public:
bool compare(TreeNode* l,TreeNode* r){
if(!l&&!r){
return true;
}
else if(!l||!r){
return false;
}
else{//都不为空
if(l->val!=r->val){//如果值都不等直接false
return false;
}
return compare(l->left,r->right)&&compare(l->right,r->left);
}
}
bool isSymmetric(TreeNode* root) {
if(!root){
return true;
}
return compare(root->left,root->right);
}
};
个人感觉解析中说的后序遍历不是很对,本题就是一个对外侧节点和内侧节点的分别比较,并不存在什么遍历。
使用迭代写法,队列和栈可以,主要用于比较容器前面两个元素是否相等。
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if(!root){
return true;
}
queue<TreeNode*> q;
q.push(root->left);
q.push(root->right);
while(!q.empty()){
TreeNode* leftNode=q.front();
q.pop();
TreeNode* rightNode=q.front();
q.pop();
if(!leftNode&&!rightNode){//都为空说明对称
continue;
}
if(!leftNode||!rightNode||leftNode->val!=rightNode->val){
return false;//不等直接false
}
q.push(leftNode->left);
q.push(rightNode->right);
q.push(leftNode->right);
q.push(rightNode->left);
}
return true;
}
};