zoukankan      html  css  js  c++  java
  • 101. 对称二叉树

    101. 对称二叉树

    题目链接: 101. 对称二叉树(简单)

    给定一个二叉树,检查它是否是镜像对称的。

    例如,二叉树 [1,2,2,3,4,4,3] 是对称的。

        1
      / \
    2   2
    / \ / \
    3 4 4 3

    但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:

        1
      / \
    2   2
      \   \
      3   3

    进阶:

    你可以运用递归和迭代两种方法解决这个问题吗?

    题解

    思路:根据题意可知,判断一棵树是不是镜像对称的,就是对比根节点的“左子树”和“右子树”,镜像对称就是要求“左子树翻转以后和右子树一模一样”。对左子树可以采取左右中的遍历方式,而对右子树采取右左中的遍历方式。

    代码(C++):

    //方法一:递归(1.确定递归函数的参数和返回值;2.确定终止条件;3.确定单层递归的逻辑)
    class Solution1 {
    public:
        bool isSymmetric(TreeNode* root) {
            if (root == nullptr) return true;
            return compare(root->left, root->right);
        }
    ​
        bool compare(TreeNode* node1, TreeNode* node2) {
            if (node1 == nullptr && node2 != nullptr) return false;
            else if (node1 != nullptr && node2 == nullptr) return false;
            else if (node1 == nullptr && node2 == nullptr) return true;
            else if (node1->val != node2->val) return false;
            else if (node1->val == node2->val) {//其实这里的if语句写不写都可,因为前面把“这种情况”以外的所有情况都列举出来了
                bool result1 = compare(node1->left, node2->right);//左子树:左;右子树:右
                bool result2 = compare(node1->right, node2->left);//左子树:右;右子树:左
                bool result = result1 && result2;//左子树:中;右子树:中(逻辑处理)
                return result;
            }
            return false;
        }
    };
    ​
    //方法二:迭代
    //使用队列实现
    class Solution2 {
    public:
        bool isSymmetric(TreeNode* root) {
            if (root == nullptr) return true;
            if (root->left == nullptr && root->right == nullptr) return true;
            else if (root->left == nullptr || root->right == nullptr) return false;
            //以上排除了根节点左右孩子都为空,根节点左右孩子其中一个为空的情况,剩下的就是左右孩子都不为空的情况
            queue<TreeNode*> que;
            que.push(root->left);
            que.push(root->right);
            while (!que.empty()) {
                TreeNode* node1 = que.front();
                que.pop();
                TreeNode* node2 = que.front();
                que.pop();
                if (node1->val != node2->val) return false;
    ​
                if (node1->left == nullptr && node2->right == nullptr);
                else if (node1->left == nullptr || node2->right == nullptr) return false;
                else {
                    que.push(node1->left);
                    que.push(node2->right);
                }
    ​
                if (node1->right == nullptr && node2->left == nullptr);
                else if (node1->right == nullptr || node2->left == nullptr) return false;
                else {
                    que.push(node1->right);
                    que.push(node2->left);
                }
            }
            return true;
        }
    };
    ​
    //迭代
    //使用队列实现,代码更简洁
    class Solution3 {
    public:
        bool isSymmetric(TreeNode* root) {
            if (root == nullptr) return true;
            queue<TreeNode*> que;
            que.push(root->left);
            que.push(root->right);
            while (!que.empty()) {
                TreeNode* node1 = que.front();
                que.pop();
                TreeNode* node2 = que.front();
                que.pop();
                if (node1 != nullptr && node2 == nullptr) return false;
                else if (node1 == nullptr && node2 != nullptr) return false;
                else if (node1 == nullptr && node2 == nullptr);
                else if (node1->val != node2->val) return false;
                else if (node1->val == node2->val) { //其实这里的if语句写不写都可,因为前面把“这种情况”以外的所有情况都列举出来了
                    que.push(node1->left);
                    que.push(node2->right);
                    que.push(node1->right);
                    que.push(node2->left);
                }
            }
            return true;
        }
    };
    ​
    //迭代
    //使用“栈”实现,把左右两个子树要比较的元素顺序放进一个容器,然后成对成对的取出来进行比较,只要将上面使用“队列”的方法中的队列改成栈即可,其余的代码不用改变
    //这里给出更简洁的代码
    class Solution4 {
    public:
        bool isSymmetric(TreeNode* root) {
            if (root == nullptr) return true;
            stack<TreeNode*> sta;
            sta.push(root->left);
            sta.push(root->right);
            while (!sta.empty()) {
                TreeNode* node1 = sta.top();
                sta.pop();
                TreeNode* node2 = sta.top();
                sta.pop();
                if (!node1 && !node2) continue;
                if (!node1 || !node2 || (node1->val != node2->val)) {
                    return false;
                }
                sta.push(node1->left);
                sta.push(node2->right);
                sta.push(node1->right);
                sta.push(node2->left);
            }
            return true;
        }
    };

    代码(Java):

    //迭代
    class
    Solution { public boolean isSymmetric(TreeNode root) { if (root == null) return true; Deque<TreeNode> que = new LinkedList<>(); que.offer(root.left); que.offer(root.right); while (!que.isEmpty()) { TreeNode node1 = que.poll(); TreeNode node2 = que.poll(); ​ if (node1 == null && node2 == null); else if (node1 == null || node2 == null || (node1.val != node2.val)) return false; else { que.offer(node1.left); que.offer(node2.right); que.offer(node1.right); que.offer(node2.left); } } return true; } }

    分析:

    方法一:递归

    • 时间复杂度:这里遍历了这棵树,渐进时间复杂度为O(n)。

    • 空间复杂度:与递归使用的栈空间有关,这里递归层数不超过 n,故渐进空间复杂度为 O(n)。

    方法二:迭代

    • 时间复杂度:O(n),遍历了这棵树。

    • 空间复杂度:这里用一个队列来维护节点,每个节点最多进队一次,出队一次,队列中最多不会超过 n 个点,故渐进空间复杂度为 O(n)。

    参考链接

    代码随想录

  • 相关阅读:
    Manjaro Linux自带的Python没有安装IDLE的解决办法
    Python入门 | IDLE的介绍和使用方法
    用U盘装CentOS 7出现dracut:/#问题的解决办法
    在Ubuntu下,如何安装坚果云deb文件
    windows7下进行ubuntu U盘启动盘的制作
    oracle 死锁和锁等待区别
    MySQL数据库设计总结
    oracle开机自启
    微信备份提示当前网络状况复杂,请尝试使用其他网络的解决方法
    ORA-27090 Unable to reserve kernel resources for asynchronous disk I/O
  • 原文地址:https://www.cnblogs.com/wltree/p/15622603.html
Copyright © 2011-2022 走看看