力扣刷题之对称二叉树(一)

简介: 力扣刷题之对称二叉树(一)

对称二叉树


image.png

本题考二叉树对称,镜像对称,也就是根节点的左子树和右子树是不是相互翻转的,理解这一天我们其实就知道了,这题就是考比较两个树(这两个树是根节点的左右子树)

递归


我们将根节点的左子树记做 left,右子树记做 right。比较 left 是否等于 right,不等的话直接返回就可以了。

如果相当,比较 left 的左节点和 right 的右节点,再比较 left 的右节点和 right 的左节点

比如看下面这两个子树(他们分别是根节点的左子树和右子树),能观察到这么一个规律:

左子树 22 的左孩子 == 右子树 22 的右孩子

左子树 22 的右孩子 == 右子树 22 的左孩子

    2         2
   / \       / \
  3   4     4   3
 / \ / \   / \ / \
8  7 6  5 5  6 7  8

下面根据递归三部曲来分析


image.png

1.确定递归函数的参数和返回值

因为我们要比较的是根节点的两个子树是否相互翻转,进而判读左右子树是否相等,所以返回值是bool类型,我们要比较的是两个子树,因此参数自然是左子树和右子树。

1. bool dfs(TreeNode* left,TreeNode* right)
2.

2.确定终止条件

  • 左右节点都为空
  • 两个节点有一个为空
  • 两个节点的值不相等
if(left==nullptr&&right==nullptr)
{
    return true;
}
if(left==nullptr||right==nullptr)
{
    return false;
}
if(left->val!=right->val)
{
    return false;
}

3.确定单层循环的逻辑

递归比较左节点的左孩子和右节点的右孩子;以及比较左节点的右孩子和右节点的左孩子;

return dfs(left->left,right->right) && dfs(left->right,right->left);

代码:

class Solution {
public:
    bool isSymmetric(TreeNode* root) {
            if(root==nullptr)
            {
                return true;
            }
            return dfs(root->left,root->right);
    }
   bool dfs(TreeNode* left,TreeNode* right)
    {
        if(left==nullptr&&right==nullptr)
        {
            return true;
        }
        if(left==nullptr||right==nullptr)
        {
            return false;
        }
        if(left->val!=right->val)
        {
            return false;
        }
        return dfs(left->left,right->right)&&dfs(left->right,right->left);
    }
};

迭代


通过队列来判断根节点的左子树和右子树的内侧和外侧是否相等,如动画所示:

afb932e064c9bc2d5162dfda52830e44.gif

class Solution {
public:
    bool isSymmetric(TreeNode* root) {
      if(root==nullptr)
      {
          return true;
      }
      queue<TreeNode*> q;
      q.push(root->left);// 将左子树头结点加入队列
      q.push(root->right);// 将右子树头结点加入队列
      while(!q.empty())
      {
          TreeNode* leftNode=q.front();q.pop();
          TreeNode* rightNode=q.front();q.pop();
          if(leftNode==nullptr&&rightNode==nullptr)// 左节点为空、右节点为空,此时说明是对称的
          {
             continue;
          }
          // 接下来就要判断这两个树是否相互翻转
          if(leftNode==nullptr||rightNode==nullptr)
          {
              return false;
          }
          if(leftNode->val!=rightNode->val)
          {
              return false;
          }
          q.push(leftNode->left); // 加入左节点左孩子
          q.push(rightNode->right);// 加入右节点右孩子
          q.push(leftNode->right);// 加入左节点右孩子
          q.push(rightNode->left); // 加入右节点左孩子
      }
      return true;
    }
};

牛刀小试(下节讲解)


100. 相同的树 - 力扣(LeetCode) (leetcode-cn.com)

572. 另一棵树的子树 - 力扣(LeetCode) (leetcode-cn.com)

相关文章
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
280页PDF,全方位评估OpenAI o1,Leetcode刷题准确率竟这么高
【10月更文挑战第24天】近年来,OpenAI的o1模型在大型语言模型(LLMs)中脱颖而出,展现出卓越的推理能力和知识整合能力。基于Transformer架构,o1模型采用了链式思维和强化学习等先进技术,显著提升了其在编程竞赛、医学影像报告生成、数学问题解决、自然语言推理和芯片设计等领域的表现。本文将全面评估o1模型的性能及其对AI研究和应用的潜在影响。
39 1
|
3月前
|
数据采集 负载均衡 安全
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
本文提供了多个多线程编程问题的解决方案,包括设计有限阻塞队列、多线程网页爬虫、红绿灯路口等,每个问题都给出了至少一种实现方法,涵盖了互斥锁、条件变量、信号量等线程同步机制的使用。
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
|
2月前
【LeetCode 31】104.二叉树的最大深度
【LeetCode 31】104.二叉树的最大深度
20 2
|
2月前
【LeetCode 29】226.反转二叉树
【LeetCode 29】226.反转二叉树
18 2
|
2月前
【LeetCode 28】102.二叉树的层序遍历
【LeetCode 28】102.二叉树的层序遍历
17 2
|
2月前
【LeetCode 43】236.二叉树的最近公共祖先
【LeetCode 43】236.二叉树的最近公共祖先
21 0
|
2月前
【LeetCode 38】617.合并二叉树
【LeetCode 38】617.合并二叉树
15 0
|
2月前
【LeetCode 37】106.从中序与后序遍历构造二叉树
【LeetCode 37】106.从中序与后序遍历构造二叉树
19 0
|
2月前
【LeetCode 34】257.二叉树的所有路径
【LeetCode 34】257.二叉树的所有路径
21 0
|
2月前
【LeetCode 32】111.二叉树的最小深度
【LeetCode 32】111.二叉树的最小深度
19 0