初识Leetcode----学习(十)【相同的树、对称二叉树】

相同的树

给定两个二叉树,编写一个函数来检验它们是否相同。

如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

示例 1:

输入:       1         1
          / \       / \
         2   3     2   3

        [1,2,3],   [1,2,3]

输出: true

示例 2:

输入:      1          1
          /           \
         2             2

        [1,2],     [1,null,2]

输出: false

示例 3:

输入:       1         1
          / \       / \
         2   1     1   2

        [1,2,1],   [1,1,2]

输出: false

1.先将特殊情况判断完成,然后采用递归判断两棵树的根、左子节点、右子节点是否全部相等,如果相等则说明为相同的树,否则返回false:

class Solution {
public:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        if (p == NULL && q == NULL)   //如果两棵树的根节点同时为空,则返回true
            return true;
        else if (p == NULL || q == NULL)  //如果其中一个二叉树的根不为空而另一个二叉树的根为空的话返回false
            return false;
        else
        {
            if (p->val == q->val && isSameTree(p->left,q->left)
               && isSameTree(p->right,q->right))  //递归判断两个二叉树的左子节点与右子节点是否都相等,相等则返回true
                return true;
            else
                return false;
        }
    }
};

2.非递归方法,二叉树的四种遍历方法(层序、先序、中序、后序)都有各自的迭代方法,这里先看前序的迭代写法,相当于同时遍历两个数,然后每个节点都进行比较:

class Solution {
public:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        stack<TreeNode*> s1, s2;    //建立两个栈分别保存两个二叉树的节点信息
        if (p) s1.push(p);          //若p非空,将节点压入栈
        if (q) s2.push(q);         //若q非空,将节点压入栈
        while (!s1.empty() && !s2.empty()) {   //若两个二叉树未遍历完成,则继续迭代
            TreeNode *t1 = s1.top(); s1.pop();  //创建指针保存栈顶元素,并将该元素弹出栈
            TreeNode *t2 = s2.top(); s2.pop();
            if (t1->val != t2->val) return false; //如果指针(节点)所指数据不相同,则返回false(两个树不同)
            if (t1->left) s1.push(t1->left); //分别判断两个树的左子节点是否为空,不为空则压入栈
            if (t2->left) s2.push(t2->left);
            if (s1.size() != s2.size()) return false; //如此时栈元素数量不相同,则返回false
            if (t1->right) s1.push(t1->right);//再分别判断两个树的右子节点是否为空,不为空则压入栈
            if (t2->right) s2.push(t2->right);
            if (s1.size() != s2.size()) return false;
        }
        return s1.size() == s2.size();  //遍历完成再次判断栈中数量是否相等,以防判空
    }
};

对称二叉树

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

例如,二叉树 [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

说明:

如果你可以运用递归和迭代两种方法解决这个问题,会很加分。

1.递归方法,构造一个判断镜像的函数(传入两个参数,TreeNode* p、TreeNode* q),在该函数中递归判断是否为镜像的(对称),需要同时判断p的左子节点与q的右子节点、p的右子节点与q的左子节点是否同时相等,以此类推来比较完所有的节点:

class Solution {
public:
    bool isJingxiang(TreeNode* p,TreeNode* q)   //判断是否为镜像
    {
        if (p == NULL && q == NULL)      //根节点同时为空,返回true
            return true;
        if (p == NULL || q == NULL)      //根节点不同时为空,返回false
            return false;
        if (p->val != q->val)            //根节点所指数据不同,返回false
            return false;
        return isJingxiang(p->left,q->right) && isJingxiang(p->right,q->left);  //递归判断
    }
    bool isSymmetric(TreeNode* root) {
        if (root == NULL)
            return true;
        return isJingxiang(root->left,root->right);  //调用镜像判断函数进行对称树的判断
    }
};

2.迭代方法,使用队列存储二叉树的节点信息,利用队列的先进先出特点进行迭代,可以得出判断:

class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        if (!root) return true;  //如果根节点为空,则为镜像,返回true
        queue<TreeNode*> q1,q2;  //使用队列保存节点
        q1.push(root->left);     //先将左节点与右节点分别存入两个队列
        q2.push(root->right);
        while (!q1.empty() && !q2.empty())
        {
            TreeNode* node1 = q1.front();  //指针node1指向的是左节点
            TreeNode* node2 = q2.front();  //指针node2指向的是右节点
            q1.pop();    //将两个数据从队列中弹出 
            q2.pop();
            if (node1 && !node2 || !node1 && node2) return false;  //如果两个节点中有一个为空,则返回false
            if (node1)    //节点不为空
            {
                if (node1->val != node2->val)   //两者指向的数据不相同,返回false
                    return false;
                q1.push(node1->left);           //将左节点的左子节点与右子节点存入队列q1
                q1.push(node1->right);
                q2.push(node2->right);         //将右节点的左子节点与右子节点存入队列q2
                q2.push(node2->left);
                 //再迭代判断时,根据队列先进先出的特点,接下来比较的是左节点的左子节点与右节点的右子节点,这样就能完成迭代判断
            }
        }
        return true;  //在经过上述迭代判断之后,如果未返回值,说明该二叉树为对称树
    }
};

猜你喜欢

转载自blog.csdn.net/qq_38790716/article/details/83066869