剑指Offer28.对称的二叉树 C++

1、题目描述

请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。
例如,二叉树 [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:
输入:root = [1,2,2,3,4,4,3]
输出:true
示例 2:
输入:root = [1,2,2,null,3,null,3]
输出:false

2、VS2019上运行

使用递归的方法

#include 

struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;

    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

class Solution {
public:
    // 递归辅助函数,检查两个节点是否对称
    bool check(TreeNode* p, TreeNode* q) {
        // 如果两个节点都为空,表示对称
        if (!p && !q) return true;
        // 如果其中一个节点为空,表示不对称
        if (!p || !q) return false;
        // 检查当前节点值是否相等,且左右子树分别对称
        return p->val == q->val && check(p->left, q->right) && check(p->right, q->left);
    }

    // 判断二叉树是否对称
    bool isSymmetric(TreeNode* root) {
        // 调用辅助函数检查根节点的左右子树是否对称
        return check(root, root);
    }
};

int main() {
    // 创建示例二叉树 [1,2,2,3,4,4,3]
    //          1
    //         / \
    //        2   2
    //       / \ / \
    //      3  4 4  3

    TreeNode* root = new TreeNode(1);
    root->left = new TreeNode(2);
    root->right = new TreeNode(2);
    root->left->left = new TreeNode(3);
    root->left->right = new TreeNode(4);
    root->right->left = new TreeNode(4);
    root->right->right = new TreeNode(3);

    // 创建 Solution 类的实例
    Solution solution;

    // 判断二叉树是否对称
    bool isSymmetric = solution.isSymmetric(root);

    // 输出判断结果
    std::cout << "该二叉树是否对称: " << (isSymmetric ? "是" : "否") << std::endl;

    return 0;
}

运行结果:
该二叉树是否对称: 是

3、解题思路

  • 在这段代码中,我们定义了一个 Solution 类,其中包含了两个函数:check 和 isSymmetric。
    函数 check 是一个递归辅助函数,用于检查两个二叉树节点是否对称。该函数接受两个参数 p 和 q,分别表示要比较的两个节点。
  • 在 check 函数中,我们首先对两个节点进行判断:
    1.如果两个节点都为空,表示对称,返回 true。
    2.如果其中一个节点为空,表示不对称,返回 false。
  • 然后,我们进一步判断两个节点的值是否相等。如果相等,我们继续递归调用 check 函数来检查当前节点的左子树的左子树是否与右子树的右子树对称,并且当前节点的左子树的右子树是否与右子树的左子树对称。
  • 最后,函数 isSymmetric 是用来判断给定的二叉树是否对称的函数。在这个函数中,我们调用 check 函数来检查根节点的左右子树是否对称。如果对称,返回 true;如果不对称,返回 false。
    在主函数中,我们创建一个示例二叉树,并将其传递给 isSymmetric 函数进行判断。最后,根据返回结果,打印出二叉树是否对称的信息。

4、关于return p->val == q->val && check(p->left, q->right) && check(p->right, q->left);

  • 这段代码是在递归调用 check 函数时进行判断。它的作用是检查当前节点的值是否相等,并且同时检查当前节点的左子树的左子树与右子树的右子树是否对称,以及当前节点的左子树的右子树与右子树的左子树是否对称。
  • 具体来说,它的判断条件是:
    1.p->val == q->val:当前节点的值相等。
    2.check(p->left, q->right):递归调用 check 函数,比较当前节点的左子树的左子树和右子树的右子树是否对称。
    3.check(p->right, q->left):递归调用 check 函数,比较当前节点的左子树的右子树和右子树的左子树是否对称。
  • 如果这三个条件都满足,则返回 true,表示当前节点及其子树是对称的;否则,返回 false,表示不对称。

5、关于check(root, root)

  • 这两个 root 是不同的节点,其中一个是从 isSymmetric 函数传递下来的根节点,另一个是 check 函数递归调用时传递的左右子节点。具体来说,isSymmetric 函数接收一个二叉树的根节点作为参数,然后它调用 check 函数并传递两次相同的根节点,即 check(root, root)。
  • 在 check 函数中,我们使用两个不同的参数 p 和 q 来表示待比较的两个节点。第一次递归调用时,p 是根节点的左子节点,q 是根节点的右子节点;第二次递归调用时,p 是左子节点的左子节点,q 是右子节点的右子节点;同样,第三次和第四次递归调用时,p 和 q 分别表示相应位置的子节点。
  • 总结一下:
    1.isSymmetric 函数调用 check 函数并传递两次相同的节点作为参数,即 check(root, root)。
    2.check 函数使用不同的参数 p 和 q 表示待比较的两个节点以及其子节点。

你可能感兴趣的:(剑指Offer刷题,c++,算法,开发语言,力扣)