判断是否为对称二叉树

  • Post author:
  • Post category:其他


给你一个二叉树的根节点 root , 检查它是否轴对称。

解法一:递归

如果一个树的左子树与右子树镜像对称,那么这个树是对称的。

因此,该问题可以转化为:两个树在什么情况下互为镜像?

如果同时满足下面的条件,两个树互为镜像:

  • 它们的两个根结点具有相同的值

  • 每个树的右子树都与另一个树的左子树镜像对称,每个树的左子树也与另一个树的右子树镜像对称。

上述两个条件表明:两个树如果对称,首先根节点的值要相同,其次除了根节点的其他子树也要镜像,因此这里要用到子树之间是否是镜像的结果,因此递归函数要用到返回值bool。

我们可以实现这样一个递归函数,通过「

同步移动」两个指针

的方法来遍历这棵树,p和q,每次检查当前 pp 和 qq 节点的值是否相等,如果相等再判断左右子树是否对称。

class Solution {
public:
    bool check(TreeNode* node1, TreeNode* node2){
        //都为空
        if(!node1 && !node2) return true;
        //有一个不为空
        if((!node1 && node2) || (node1 && !node2)) return false;
        //都不为空,但是val不同
        if(node1->val != node2->val)  return false;
        //都不为空,但是val相同,还要看这两棵树是否是镜像的,要分别看外侧和内侧
        bool outside = check(node1->left, node2->right);
        bool inside = check(node1->right, node2->left);
        return outside && inside;
    }

    bool isSymmetric(TreeNode* root) {
        if(!root)return true;
        return check(root->left, root->right);
    }
};

时间复杂度:每个节点都访问了一次,因此O(n)。

空间复杂度:和递归的深度相关,每个节点都会递归一次,因此是O(n)。

解法二:迭代

两个根节点的值是否相同

一个节点的左和另一个节点的右,一个节点的右和另一个节点的左相同。

下面是用栈的实现:

/**
* 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) return true;

        stack<TreeNode*> st;
        st.push(root->left);
        st.push(root->right);

        while(st.size()){
            TreeNode* node1 = st.top();
            st.pop();
            TreeNode* node2 = st.top();
            st.pop();
            
            if(!node1 && !node2) continue;
            if((!node1 && node2) || (node1 && !node2)) return false;
            if(node1->val != node2->val) return false;
            st.push(node1->left);
            st.push(node2->right);
            st.push(node1->right);
            st.push(node2->left);
        }

        return true;
    }
};

时间复杂度:每个节点会被访问一次,O(n)。

空间复杂度:最多不会超过n个节点,O(n)。



版权声明:本文为ff_gogo原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。