101. Symmetric Tree

本文介绍了一种检查二叉树是否为自身镜像的方法,即是否围绕中心对称。通过递归和非递归两种方式实现,递归方法通过比较左子树和右子树来判断对称性,非递归方法则使用栈来存储节点进行逐层比较。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).

For example, this binary tree [1,2,2,3,4,4,3] is symmetric:

    1
   / \
  2   2
 / \ / \
3  4 4  3

But the following [1,2,2,null,3,null,3] is not:

    1
   / \
  2   2
   \   \
   3    3

Note:
Bonus points if you could solve it both recursively and iteratively.

对比left.left, right.right && left.right, right.left,如果val相等,继续递归。注意以下几点:

1、如果root==null,返回true

2、如果left或者right等于null,不能访问其左右节点和val,否则会outstack,所以要先判断left或者right等不等于null

代码如下:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public boolean isSymmetric(TreeNode root) {
        if (root == null) {
            return true;
        }
        return helper(root.left, root.right);
    }
    public boolean helper(TreeNode left, TreeNode right) {
        /*if (left == null && right == null) {
            return true;
        }
        if (left == null || right == null) {
            return false;
        }*/
        //above lines can simplify as following
        if (left == null || right == null) {
            return left == right;
        } 
        if (left.val != right.val) {
            return false;
        }
        return helper(left.left, right.right) && helper(left.right, right.left);
    }
}

Non-recursive(use Stack)--460ms:

public boolean isSymmetric(TreeNode root) {
    if(root==null)  return true;
    
    Stack<TreeNode> stack = new Stack<TreeNode>();
    TreeNode left, right;
    if(root.left!=null){
        if(root.right==null) return false;
        stack.push(root.left);
        stack.push(root.right);
    }
    else if(root.right!=null){
        return false;
    }
        
    while(!stack.empty()){
        if(stack.size()%2!=0)   return false;
        right = stack.pop();
        left = stack.pop();
        if(right.val!=left.val) return false;
        
        if(left.left!=null){
            if(right.right==null)   return false;
            stack.push(left.left);
            stack.push(right.right);
        }
        else if(right.right!=null){
            return false;
        }
            
        if(left.right!=null){
            if(right.left==null)   return false;
            stack.push(left.right);
            stack.push(right.left);
        }
        else if(right.left!=null){
            return false;
        }
    }
    
    return true;
}

<think>嗯,用户让我给这段判断二叉树是否对称的代码加上必要的注释。首先,我需要理解这段代码的结构和逻辑,这样才能写出有用的注释。 首先看结构,用户提供了两个函数:isSameTree和isSymmetric。isSymmetric是入口函数,接收根节点,然后调用isSameTree检查左右子树是否对称。而isSameTree函数实际上是在比较两个子树是否镜像对称,这可能函数名有点误导,因为通常isSameTree是用来判断两棵树是否完全相同,但这里其实是比较对称的情况。不过函数内部递归调用的时候,leftTree的左边和rightTree的右边比较,左边右边和右边左边比较,这样确实是镜像对称的逻辑。所以可能需要注释说明这个函数的作用其实是检查两棵树是否镜像对称,而不是完全相同。 接下来,我要逐行分析代码,给关键部分添加注释。比如在isSameTree函数里,首先判断两个节点是否都为空,返回true。如果其中一个为空另一个不为空,返回false。然后比较节点值是否相等。最后递归检查左子树的左和右子树的右,以及左子树的右和右子树的左。这些步骤都需要注释说明。 对于isSymmetric函数,如果根节点为空,直接返回true。否则检查左右子树是否镜像。这里要说明根为空的情况,以及调用isSameTree的参数。 需要注意的是,注释要简明扼要,解释每个条件判断和递归调用的目的。可能用户对递归的部分不太清楚,所以需要说明递归的逻辑是如何实现镜像对称的判断的。同时,要指出这个函数的时间复杂度和空间复杂度,帮助理解性能。 另外,可能用户对函数名的混淆会有疑问,所以要在注释中澄清isSameTree在这里的实际作用,避免误解。比如可以重命名函数为isMirror,但代码中已经用了isSameTree,所以注释要说明这一点。 最后,确保注释用中文,符合用户的要求,并且符合格式要求,比如行内公式用$...$,独立公式用$$...$$,但这段代码可能不需要数学公式,所以主要关注代码逻辑的解释。</think>```c /** * Definition for a binary tree node. * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * }; */ // 判断两棵子树是否镜像对称的辅助函数 // 参数:leftTree - 左子树根节点,rightTree - 右子树根节点 bool isSameTree(struct TreeNode *leftTree, struct TreeNode *rightTree){ // 情况1:两个节点都为空 → 对称 if(leftTree == NULL && rightTree == NULL){ return true; } // 情况2:只有一个节点为空 → 不对称 if(leftTree == NULL || rightTree == NULL){ return false; } // 情况3:节点值不相等 → 不对称 if(leftTree -> val != rightTree -> val){ return false; } // 递归判断镜像对称: // 1.左子树的左孩子 与 右子树的右孩子 比较 // 2.左子树的右孩子 与 右子树的左孩子 比较 return isSameTree(leftTree -> left, rightTree -> right) && isSameTree(leftTree -> right, rightTree -> left); } // 主函数:判断二叉树是否轴对称 bool isSymmetric(struct TreeNode* root) { // 空树视为对称 if(root == NULL){ return true; } // 检查左右子树是否镜像对称 return isSameTree(root -> left, root -> right); } ``` 代码执行流程分析(时间复杂度 $O(n)$,空间复杂度 $O(h)$,h为树高): 1. 主函数处理空树特殊情况 2. 调用辅助函数对比左右子树 3. 辅助函数通过递归逐层比较: - 镜像对称必须同时满足: * 当前节点值相等 * 左子树左分支 ≡ 右子树右分支 * 左子树右分支 ≡ 右子树左分支 4. 递归终止条件:遇到空节点或发现不对称立即返回 注意:虽然函数名为isSameTree,但实际实现的是镜像对称比较,这是解题的关键设计点
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值