判断二叉树是否是水平对称的 Symmetric Tree

题目:Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).For example, this binary tree is symmetric:题目源自于Leetcode。

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


之前错误的思路:先中序遍历,在遍历过程中生成整个树的中序序列,然后判断这个序列是否是回文序列。这个错误在于“二叉树对称”是“中序序列是回文”的充分不必要条件

//错误方案
class Solution {
public:
    bool isSymmetric(TreeNode *root) {
        if(root == NULL)
            return true;
            
        vector<int> v;
        fun(root, v);
        int n = v.size();
        if(n%2==0) //必定是奇数个元素才能对称
            return false;
        int i;
        for(i=1;i<=n/2;i++) //判断是否是回文
        {
            if(v[n/2+i] != v[n/2-i])
                return false;
        }
        return true;
    }
    
    void fun(TreeNode *root, vector<int> &v)
    {
        if(root != NULL)
        {
            fun(root->left, v);
            v.push_back(root->val);
            fun(root->right, v);
        }
    }
};


思路1:递归思想,对称二叉树的左右两个子树一定是镜面对称的。对于镜面对称判断其左右结点的孩子是否是镜面的,递归进行下去。

class Solution {
public:
    bool isSymmetric(TreeNode *root) {
        if(root == NULL)
            return true;
        return isSym(root->left, root->right);
    }
    
    bool isSym(TreeNode *p1, TreeNode *p2)
    {
        if(p1 == NULL && p2 == NULL)
            return true;
        else if(p1 == NULL || p2 == NULL)
            return false;
        else if(p1->val == p2->val)
        {
            return isSym(p1->left, p2->right) && isSym(p1->right, p2->left);
        }
        else
            return false;
    }
};

思路2:先将原二叉树镜面对称过来变成另一个二叉树,然后判断两个二叉树是否是完全相同的。

class Solution {
public:
    bool isSymmetric(TreeNode *root) {
        TreeNode *mi = mirror(root);
        return isEqual(mi, root);
    }
    
    TreeNode* mirror(TreeNode *root) //生成镜像化的二叉树
    {
        if(root == NULL)
            return NULL;
        TreeNode *nroot = new TreeNode(root->val);
        nroot->left = mirror(root->right);
        nroot->right = mirror(root->left);
        return nroot;
    }
    
    bool isEqual(TreeNode *p1, TreeNode *p2) //判断两个二叉树是否完全相等
    {
        if(p1 == NULL && p2 == NULL)
            return true;
        else if(p1 == NULL || p2 == NULL)
            return false;
        
        if(p1->val == p2->val)
            return isEqual(p1->left, p2->left) && isEqual(p1->right, p2->right);    
        else
            return false;
    }
};

思路3:层序遍历。层序遍历过程中不漏过任何一个空的孩子,直到最底层全部为空节点才结束遍历。每一层结束时判断一次该层的结点是否是回文。

该方法的时间复杂度并不高,可是我的实现却超时了。

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

        queue<TreeNode *> q;
        vector<int> level;
        q.push(root);
        TreeNode *enode = new TreeNode(-1);//每一层结束的标记
        q.push(enode);
        int count = 0;//记录是否到达全部为空节点的最底层
        
        while(!q.empty())
        {
            TreeNode* tmp = q.front();
            q.pop();
            
            if(tmp == enode)
            {
                if(count == 0)
                    return true;
                if(!isPalin(level))
                    return false;
                level.clear();
                count = 0;
                if(!q.empty())
                {
                    q.push(enode);
                    continue;
                }
                else
                    return true;
            }
            else if(tmp == NULL)
            {
                level.push_back(-1);
                q.push(NULL);
                q.push(NULL);
            }
            else
            {
                q.push(tmp->left);
                q.push(tmp->right);
                level.push_back(tmp->val);
                count++;
            }
        }
    }
    
    bool isPalin(vector<int> &level)
    {
        int left = 0, right = level.size()-1;
        while(left < right)
        {
            if(level[left++] != level[right--])
                return false;
        }
        return true;
    }
};


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值