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

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

对称二叉树


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)

相关文章
|
15天前
|
算法 C++
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题-2
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题
|
15天前
|
算法 C++
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题-1
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题
|
15天前
|
算法
二刷力扣--二叉树(3)
二刷力扣--二叉树(3)
|
15天前
二刷力扣--二叉树(2)
二刷力扣--二叉树(2)
|
15天前
二刷力扣--二叉树(1)基础、遍历
二刷力扣--二叉树(1)基础、遍历
|
16天前
|
索引
【LeetCode刷题】二分查找:山脉数组的峰顶索引、寻找峰值
【LeetCode刷题】二分查找:山脉数组的峰顶索引、寻找峰值
|
16天前
|
算法
【LeetCode刷题】滑动窗口解决问题:串联所有单词的子串(困难)、最小覆盖子串(困难)
【LeetCode刷题】滑动窗口解决问题:串联所有单词的子串(困难)、最小覆盖子串(困难)
|
16天前
【LeetCode刷题】专题三:二分查找模板
【LeetCode刷题】专题三:二分查找模板
【LeetCode刷题】专题三:二分查找模板
|
16天前
【LeetCode刷题】前缀和解决问题:742.寻找数组的中心下标、238.除自身以外数组的乘积
【LeetCode刷题】前缀和解决问题:742.寻找数组的中心下标、238.除自身以外数组的乘积
|
16天前
【LeetCode刷题】二分查找:寻找旋转排序数组中的最小值、点名
【LeetCode刷题】二分查找:寻找旋转排序数组中的最小值、点名