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

题记:
给你一个二叉树的根节点 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

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

题目来源:
作者:LeetCode
链接:https://leetcode.cn/leetbook/read/top-interview-questions-easy/xn7ihv/
来源:力扣(LeetCode)

解题方法:

一:递归解决

判断二叉树是否是对称,需要从子节点开始比较,两个子节点的值必须相同,并且左子节点的右子节点(如果有)必须等于右子节点的左子节点,左子节点的左子节点必须等于右子节点的右子节点。就像下面图中那样
在这里插入图片描述

public boolean isSymmetric(TreeNode root) {
    if (root == null)
        return true;
    //从两个子节点开始判断
    return isSymmetricHelper(root.left, root.right);
}

public boolean isSymmetricHelper(TreeNode left, TreeNode right) {
    //如果左右子节点都为空,说明当前节点是叶子节点,返回true
    if (left == null && right == null)
        return true;
    //如果当前节点只有一个子节点或者有两个子节点,但两个子节点的值不相同,直接返回false
    if (left == null || right == null || left.val != right.val)
        return false;
    //然后左子节点的左子节点和右子节点的右子节点比较,左子节点的右子节点和右子节点的左子节点比较
    return isSymmetricHelper(left.left, right.right) && isSymmetricHelper(left.right, right.left);
}

转换为PHP代码为:

/**
  * @param TreeNode $root
  * @return Boolean
  */
 function isSymmetric($root) {
     if($root == null)
         return true;
     // 从两个子节点开始判断
     return $this->isSymmetricHelper($root->left,$root->right);
 }

 function isSymmetricHelper($left,$right){
     // 如果左右子节点都为空,说明当前节点是叶子结点,返回true
     if($left == null && $right == null)
         return true;
     // 如果当前节点只有一个子节点或者两个子节点,但两个子节点的值不同,直接返回false
     if($left == null || $right == null || $left->val != $right->val)
         return false;
     // 然后左子节点的左子节点和右子节点的右子节点比较,左子节点的右子节点和右子节点的左子节点比较
     return $this->isSymmetricHelper($left->left,$right->right) && $this->isSymmetricHelper($left->right,$right->left);
 }

二:非递归解决

非递归解决和上面原理一样,直接看下代码,不懂的代码中有详细的注释

public boolean isSymmetric(TreeNode root) {
    //队列
    Queue<TreeNode> queue = new LinkedList<>();
    if (root == null)
        return true;
    //左子节点和右子节点同时入队
    queue.add(root.left);
    queue.add(root.right);
    //如果队列不为空就继续循环
    while (!queue.isEmpty()) {
        //每两个出队
        TreeNode left = queue.poll(), right = queue.poll();
        //如果都为空继续循环
        if (left == null && right == null)
            continue;
        //如果一个为空一个不为空,说明不是对称的,直接返回false
        if (left == null ^ right == null)
            return false;
        //如果这两个值不相同,也不是对称的,直接返回false
        if (left.val != right.val)
            return false;
        //这里要记住入队的顺序,他会每两个两个的出队。
        //左子节点的左子节点和右子节点的右子节点同时
        //入队,因为他俩会同时比较。
        //左子节点的右子节点和右子节点的左子节点同时入队,
        //因为他俩会同时比较
        queue.add(left.left);
        queue.add(right.right);
        queue.add(left.right);
        queue.add(right.left);
    }
    return true;
}

转换为PHP代码为:

    public function isSymmetric($root){
        // 队列
        $queue = [];
        if($root == null)
            return true;
        // 左子节点和右子节点同时入队
        array_unshift($queue,$root->left);
        array_unshift($queue,$root->right);
        // 如果队列不为空就继续循环
        while(!empty($queue)){
            // 每两个出队
            $left = array_shift($queue);
            $right = array_shift($queue);
            // 如果都为空继续循环
            if($left == null && $right == null)
                continue;
            // 如果一个为空一个不为空,说明不是对称的,直接返回false
            if($left == null || $right == null)
                return false;
            // 如果这两个值不相同,也不是对称的,直接返回false
            if($left->val != $right->val)
                return false;
            // 这里要记住入队的顺序,他会每两个两个的出队。
            // 左子节点的左子节点和右子节点的右子节点同时
            // 入队,因为他俩会同时比较。
            // 左子节点的右子节点和右子节点的左子节点同时入队,
            // 因为他俩会同时比较
            array_unshift($queue,$left->left);
            array_unshift($queue,$right->right);
            array_unshift($queue,$left->right);
            array_unshift($queue,$right->left);
        }
        return true;
    }

方法来源:
作者:数据结构和算法
链接:https://leetcode.cn/leetbook/read/top-interview-questions-easy/xn7ihv/?discussion=QMfbGu
来源:力扣(LeetCode)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值