• 力扣第101题 c++ 递归 迭代 双方法 +注释 ~


    题目

    101. 对称二叉树

    简单

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

    示例 1:

    输入:root = [1,2,2,3,4,4,3]
    输出:true
    

    示例 2:

    输入:root = [1,2,2,null,3,null,3]
    输出:false
    

    提示:

    • 树中节点数目在范围 [1, 1000] 内
    • -100 <= Node.val <= 100

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

    思路和解题方法一(递归)

    1. compare()函数是用来判断两个节点是否对称的,其中leftright参数分别代表左右子节点。

    2. 首先我们需要判断leftright是否为空,若其中一个节点为空而另一个不为空,那么这两个节点不对称,返回false。如果两个节点都为空,则认为它们对称,返回true

    3. 如果两个节点的值不相等,则说明它们不对称,返回false

    4. 如果两个节点的值相等,则需要递归判断它们的左右子节点是否对称。具体来说,需要比较左子树的左子节点和右子树的右子节点、左子树的右子节点和右子树的左子节点是否对称,即outside = compare(left->left, right->right)inside = compare(left->right, right->left)

    5. 最后,给出判断结果,即只有当左子树的左子节点和右子树的右子节点、左子树的右子节点和右子树的左子节点都对称时,才可以认为这两个节点对称,返回isSame = outside && inside

    6. isSymmetric()函数是判断整个二叉树是否对称的。如果给定的根节点root为空,则直接返回true。否则,调用compare()函数比较根节点的左右子节点是否对称。

    7. 最后,整个程序返回的是isSymmetric()函数的返回值。

    复杂度

            时间复杂度:

                    O(n)

            时间复杂度是O(n),其中n为二叉树的节点数,因为我们需要遍历每个节点,每个节点都需要进行一次比较。

            空间复杂度

                    O(n)

            空间复杂度也是O(n),因为在递归调用compare()函数时,需要不断开辟新的栈空间来存储递归函数的参数和局部变量,最坏的情况下需要递归到最深层,此时栈空间的大小为O(n)。

    c++ 代码

     ​
    
    1. //复杂简单版
    2. class Solution {
    3. public:
    4. // 判断节点是否对称的函数
    5. bool compare(TreeNode* left, TreeNode* right) {
    6. // 首先排除空节点的情况
    7. if (left == NULL && right != NULL) return false;
    8. else if (left != NULL && right == NULL) return false;
    9. else if (left == NULL && right == NULL) return true;
    10. // 排除了空节点,再排除数值不相同的情况
    11. else if (left->val != right->val) return false;
    12. // 此时就是:左右节点都不为空,且数值相同的情况
    13. // 此时才做递归,做下一层的判断
    14. bool outside = compare(left->left, right->right); // 左子树:左、 右子树:右
    15. bool inside = compare(left->right, right->left); // 左子树:右、 右子树:左
    16. bool isSame = outside && inside; // 左子树:中、 右子树:中 (逻辑处理)
    17. return isSame;
    18. }
    19. // 判断整棵二叉树是否对称的函数
    20. bool isSymmetric(TreeNode* root) {
    21. if (root == NULL) return true;
    22. // 如果根节点不为空,调用compare()函数比较左子节点和右子节点是否对称
    23. return compare(root->left, root->right);
    24. }
    25. };
    26. //精简版
    27. class Solution {
    28. public:
    29. // 检查两个节点是否对称的函数
    30. bool check(TreeNode *p, TreeNode *q) {
    31. // 如果两个节点都为空,视为对称
    32. if (!p && !q) return true;
    33. // 如果其中一个节点为空,另一个节点非空,视为不对称
    34. if (!p || !q) return false;
    35. // 检查当前节点的值是否相等,并递归检查左子树和右子树是否对称
    36. return p->val == q->val && check(p->left, q->right) && check(p->right, q->left);
    37. }
    38. // 判断整棵二叉树是否对称的函数
    39. bool isSymmetric(TreeNode* root) {
    40. // 调用check函数,同时传入相同的根节点,判断左子树和右子树是否对称
    41. return check(root, root);
    42. }
    43. };

    思路和解题方法二(迭代)

    1. 首先检查根节点是否为空,若为空直接返回true。

    2. 创建一个队列que,并将根节点的左子树和右子树头结点依次加入队列。

    3. 进入while循环,判断队列是否为空。如果队列不为空,则继续执行循环体。

    4. 在循环体中,从队列中取出两个节点:leftNode为队列首部的节点,rightNode为队列次首部的节点。

    5. 判断左节点和右节点是否都为空。如果是,说明当前节点属于对称的部分,继续循环。

    6. 如果左节点和右节点有一个为空,或者它们的值不相等,返回false,表示不对称。

    7. 如果左节点和右节点都不为空且值相等,将其左孩子、右孩子按顺序依次加入队列,以备后续判断是否对称。

    8. 循环结束后,返回true,表示二叉树是对称的。

    复杂度

            时间复杂度:

                    O(n)

    时间复杂度为O(n),其中n是二叉树的节点数。

            空间复杂度

                    O(n)

    使用了一个队列来存储节点,因此,空间复杂度为O(n)。

    c++ 代码

    1. class Solution {
    2. public:
    3. bool isSymmetric(TreeNode* root) { // 判断二叉树是否对称的函数,传入根节点root
    4. if (root == NULL) return true; // 如果根节点为空,返回true
    5. queue que; // 创建一个队列que来存储需要判断的节点
    6. que.push(root->left); // 将左子树头结点加入队列
    7. que.push(root->right); // 将右子树头结点加入队列
    8. while (!que.empty()) { // 当队列不为空时,进行循环
    9. TreeNode* leftNode = que.front(); que.pop(); // 取出队列首部的节点leftNode
    10. TreeNode* rightNode = que.front(); que.pop(); // 取出队列次首部的节点rightNode
    11. if (!leftNode && !rightNode) { // 如果左节点为空、右节点为空,说明是对称的,继续循环
    12. continue;
    13. }
    14. // 左右一个节点不为空,或者都不为空但数值不相同,返回false
    15. if ((!leftNode || !rightNode || (leftNode->val != rightNode->val))) {
    16. return false; // 如果左右节点有一个为空或者值不相等,直接返回false,表示当前二叉树不对称
    17. }
    18. // 加入左节点左孩子、右节点右孩子、左节点右孩子、右节点左孩子
    19. que.push(leftNode->left); // 左节点的左孩子
    20. que.push(rightNode->right); // 右节点的右孩子
    21. que.push(leftNode->right); // 左节点的右孩子
    22. que.push(rightNode->left); // 右节点的左孩子
    23. }
    24. return true; // 当循环结束时,说明整个二叉树都对称,返回true
    25. }
    26. };

    觉得有用的话可以点点赞,支持一下。

    如果愿意的话关注一下。会对你有更多的帮助。

    每天都会不定时更新哦  >人<  。

  • 相关阅读:
    【云原生&微服务九】SpringCloud之Feign实现声明式客户端负载均衡详细案例
    【数据结构】优先级队列(堆)
    人工智能学习03——mnist手写数字实战
    GCC优化
    HTTP,HTTPS,WebSocket协议辨析
    商务软件开发网课答案
    京东云联合Forrester咨询发布混合云报告 云原生成为驱动产业发展新引擎
    OAuth 2.0一键登录那些事
    图神经网络入门基础
    【SpringBoot应用篇】SpringBoot+Redis实现接口幂等性校验
  • 原文地址:https://blog.csdn.net/jgk666666/article/details/133621704