代码随想录算法训练营第十五天|树的层序遍历 、226.翻转二叉树 、101.对称二叉树

层序遍历(广度优先遍历):

遍历思路:
借用队列来实现。
若根节点不为空,则先将根节点放入队列,
随后,在while循环中,判断队列当前的size,队列的size就是树在该层中的节点数量,所以有几个节点就要利用for循环分别将这几个节点的子节点再放入队列

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        queue<TreeNode*> MyQueue;
        vector<vector<int>> Res;
        vector<int> Temp;
        TreeNode* cur = root;

        if(root == nullptr)
          return Res;

        MyQueue.push(cur);
        
        while(!MyQueue.empty())
        {
            int size = MyQueue.size();
            for(int i=0;i<size;i++)
            {
                cur = MyQueue.front();
                Temp.push_back(cur->val);
                MyQueue.pop();
                
                if(cur->left) MyQueue.push(cur->left);
                if(cur->right) MyQueue.push(cur->right);
            }
            Res.push_back(Temp);
            Temp.clear();            
        }
        return Res;
    }
};

以下十题都可以安装这个思路进行编写:

  • 102.二叉树的层序遍历
  • 107.二叉树的层次遍历II
  • 199.二叉树的右视图
  • 637.二叉树的层平均值
  • 429.N叉树的层序遍历
  • 515.在每个树行中找最大值
  • 116.填充每个节点的下一个右侧节点指针
  • 117.填充每个节点的下一个右侧节点指针II
  • 104.二叉树的最大深度
  • 111.二叉树的最小深度

翻转二叉树 

题目链接:力扣

解题思路:这道题最关键的点在于 想清楚用那种遍历方式进行遍历
——前序和后序遍历较方便,用中序遍历会很绕,容易给自己踩坑

递归法

其实还是前序遍历的逻辑,先交换左右子树节点,然后交换左子树,再交换右子树

    TreeNode* invertTree1(TreeNode* root) {

        if(root == nullptr)
        return nullptr;

        TreeNode* Temp = root->left;
        root->left =root->right;
        root->right = Temp;

        invertTree(root->left);
        invertTree(root->right);
        return root;

    }

 迭代法

在前序遍历的基础上加以改动

 TreeNode* invertTree(TreeNode* root)
    {
        queue<TreeNode*> myqueue;
        TreeNode* cur = root;
        if(!cur) return nullptr;

        myqueue.push(cur);

        while(!myqueue.empty())
        {
            cur = myqueue.front();
            myqueue.pop();
            swap(cur->left, cur->right);

            if(cur->right) myqueue.push(cur->right);
            if(cur->left)  myqueue.push(cur->left);
        }

        return root;
    }

对称二叉树

递归法

题目链接:力扣 

解题思路:本质是比较根节点的左子树与右子树是不是相互翻转的,即我们要比较的是两个树(这两个树是根节点的左右子树),所以在递归遍历的过程中,也是要同时遍历两棵树。

 一个树的遍历顺序是左右中,一个树的遍历顺序是右左中。

class Solution {
public:
    bool isSymmetric(TreeNode* root) {

        if(!root)  return true;
        return compare(root->left,root->right);
    }

    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;
        else return compare(left->left,right->right) && compare(left->right, right->left);
    }

};

迭代法 

逻辑和递归法是一样的,使用队列来比较两个树(根节点的左右子树)是否相互翻转

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;
            }

            // 左右一个节点不为空,或者都不为空但数值不相同,返回false
            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;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值