【LeetCode101. 对称二叉树】—— 二叉树遍历

101. 对称二叉树

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

示例 1:

image.png

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

示例 2:

image.png

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

提示:

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

思考:

本题的目标是判断二叉树的对称性,比较的是所有的左右子树是否相同,这就要求我们在遍历的过程中比较左子树的外层与右子树的外层相同,内侧与内侧相同。

image.png

即:

  • 左子树2的左孩子 == 右子树2的右孩子
  • 左子树2的右孩子 == 右子树2的左孩子

而同样的,在遍历的方式上,我们可以选用递归法或是迭代法。其中,迭代法的本质其实就是层级遍历。

递归法:

递归法的难点就在于找到终止条件,以及每一次递归所要干的事。在本题中,因为要返回的是bool类型值,所以我们的终止条件其实十分简单,即不断判断是否对称,一旦出现不对称的情况,就返回false值。

而不对称的情况莫过于两种:

  1. 左右结点中有一个为空节点,另一个不为空。
  2. 左右结点对应的val值不相等。

我们使用深度优先遍历的方法,传入左右两个结点,进行比较,一轮比较结束后,再对内侧两节点以及外侧两节点进行递归比较。

//递归法
class Solution {
public:
    bool dfs(TreeNode* left, TreeNode* right)
    {
        if (left == NULL && right == NULL)
        {
            return true;
        }
        if (left == NULL || right == NULL)
        {
            return false;
        }
        if (left->val != right->val)
        {
            return false;
        }
        return dfs(left->left, right->right) && dfs(left->right, right->left);
    }
    bool isSymmetric(TreeNode* root) {
        //考虑空节点情况
        if (root == NULL)
        {
            return true;
        }
        return dfs(root->left,root->right);
    }
};

迭代法:

而运用迭代法,我们所使用的是最为经典的层序遍历的方式,使用队列这种数据结构(用栈或者数组等都可以),将对应的左右结点先存入队列中,再每一次取出两个结点,进行两两比较即可,一旦出现不对称的情况,则返回false值,若是成功完成全部遍历,则返回true。

//迭代法(层序遍历)
class Solution2
{
public:
    bool isSymmetric(TreeNode* root)
    {
        //判断空节点以及只有根节点的情况
        if (root == NULL || (root->left == NULL && root->right == NULL))
        {
            return true;
        }

        queue<TreeNode*> que;//初始化队列
        que.push(root->left);
        que.push(root->right);

        while (!que.empty())
        {
            //从队列中取出结点
            TreeNode* left = que.front();
            que.pop();
            TreeNode* right = que.front();
            que.pop();
            //进行判断
            if (left == NULL && right == NULL)
            {
                continue;
            }
            if (left == NULL || right == NULL)
            {
                return false;
            }
            if (left->val != right->val)
            {
                return false;
            }
            
            //添加子节点到队列(即使是空节点也加入)
            que.push(left->left);
            que.push(right->right);
            que.push(left->right);
            que.push(right->left);
        }
        return true;
    }
};

参考:代码随想录

往期回顾:
LeetCode226. 翻转二叉树
专题一 二叉树层序遍历
LeetCode102. 二叉树的层序遍历
LeetCode144、145、94. 二叉树遍历
LeetCode18. 四数之和
LeetCode15. 三数之和
LeetCode383. 赎金信
LeetCode454. 四数相加 II
LeetCode1. 两数之和
LeetCode202. 快乐数
LeetCode350. 两个数组的交集 II
LeetCode349. 两个数组的交集
LeetCode1002. 查找共用字符

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值