代码随想录训练营第十五天|102. 二叉树的层序遍历107. 二叉树的层序遍历II199.二叉树的右视图637.二叉树的层平均值226.反转二叉树101.对称二叉树

102. 二叉树的层序遍历

层序遍历是一种树遍历方法,其中每个节点都被访问一次,并且每个节点都按照从上到下、从左到右的顺序被访问。

代码中定义了一个名为Solution的类,该类中包含一个公共成员函数levelOrder,它接收一个指向二叉树根节点的指针root,并返回一个二维整数向量,表示二叉树的层序遍历结果。

levelOrder函数使用了队列数据结构来实现层序遍历。首先,如果根节点不为空,将其加入队列。然后,进入循环,直到队列为空为止。在每次循环中,先获取当前队列的大小(即当前层的节点数),然后创建一个整数向量vec来存储当前层的节点值。接下来,通过循环访问队列中的每个节点,将其值加入vec向量,并将其左右子节点(如果存在)加入队列。最后,将vec向量加入结果向量result中。

在循环内部,注释提到了一个重要注意事项:在循环中使用固定大小size来限制循环次数,而不是使用动态变化的que.size()。这是因为队列的大小在循环过程中会不断变化,如果使用que.size()作为循环条件,会导致循环次数不正确。

最终,函数返回结果向量result,其中包含了二叉树的层序遍历结果。

这个程序的时间复杂度是O(n),其中n是二叉树的节点数。因为每个节点只被访问一次,并且访问每个节点的操作都是常数时间的。空间复杂度也是O(n),因为需要使用一个队列来存储每一层的节点。

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        queue<TreeNode*> que;
        if (root != NULL) que.push(root);
        vector<vector<int>> result;
        while (!que.empty()) {
            int size = que.size();
            vector<int> vec;
            // 这里一定要使用固定大小size,不要使用que.size(),因为que.size是不断变化的
            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

 只是在最后反转一下就可以

class Solution {
public:
    vector<vector<int>> levelOrderBottom(TreeNode* root) {
        queue<TreeNode *> que;
        if(root != nullptr) que.push(root);
        vector<vector<int>> result;
        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 != nullptr)
                que.push(node->left);
                if(node->right != nullptr)
                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;
        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); 
                if (node->left) que.push(node->left);
                if (node->right) que.push(node->right);
            }
        }
        return result;
    }
};

if (i == (size - 1)) result.push_back(node->val); 可以将一行中最后一个放入result中

637.二叉树的层平均值

for循环负责循环同行里面的元素,sum会在一行结束之后归零,以实现累加操作

class Solution {
public:
    vector<double> averageOfLevels(TreeNode* root) {
        queue<TreeNode*> que;
        if(root!=nullptr) que.push(root);
        vector<double> result;

        while(!que.empty())
        {
            int size = que.size();
            double sum = 0;
            for(int i = 0; i < size;i++)
            {
                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/size);
        }
        return result;
    }
};

226反转二叉树

递归三步:确定元素和返回值;确定单层递归逻辑;确定结束条件

class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if(root == nullptr) return root;
        swap(root->left, root->right);
        invertTree(root->left);
        invertTree(root->right);
        return root;

    }
};

 这里采用的是前序遍历,也可以使用后序遍历,但是不可以使用中序遍历,会导致先反转的树枝再次被反转过来

101.对称二叉树

思路:可以用刚才的反转二叉树与测试的二叉树比较,但是地址问题存在

class Solution {
public:
    TreeNode *invertTree(TreeNode *root)
    {
        if (root == nullptr)
            return root;
        swap(root->left, root->right);
        invertTree(root->left);
        invertTree(root->right);
        return root;
    }
    bool isSymmetric(TreeNode* root) {
        if(root == nullptr)return true;
        return root==invertTree(root)?true:false;
    }
};

 

首先对于五特殊情况:

1.左空右空2.左空右不空3.左不空右空4.下层left right不等5.下层left right相等

1.true2.false3.false4.false5.递归遍历下一层

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 outsider=compare(left->left, right->right);
        bool insider=compare(left->right, right->left);
        bool issame = (outsider && insider);
        return issame;
    }
    bool isSymmetric(TreeNode* root) {
        if(root == nullptr)return true;
        return compare(root->left, root->right);
    }
};

提示必须先排除空指针,不可先检查,会导致出错。

 

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值