Skip to content

一、问题描述

给定一个二叉树的根节点 root,检查它是否是镜像对称的。即,交换它的左子树和右子树,两棵树是否仍然是相同的。

二、方案一:递归法

1、思路

递归比较左子树的左节点和右子树的右节点,以及左子树的右节点右子树的左节点。如果都相等,则继续递归比较下一层。

2、代码实现

go
func isSymmetric(root *TreeNode) bool {
    if root == nil {
        return true
    }
    return checkSymmetric(root.Left, root.Right)
}
func checkSymmetric(left, right *TreeNode) bool {
    if left == nil && right == nil {
        return true
    }
    if left == nil || right == nil {
        return false
    }
    if left.Val != right.Val {
        return false
    }
    return checkSymmetric(left.Left, right.Right) && checkSymmetric(left.Right, right.Left)
}

3、复杂度分析

  • 时间复杂度:O(n),其中 n 是树中节点的数量。
  • 空间复杂度:O(n),递归调用栈的深度取决于树的高度,最坏情况下树完全不平衡,高度为 n。

三、方案二:迭代法

1、思路

使用队列进行迭代比较。首先将根节点的左右子节点放入队列中,然后每次从队列中取出两个节点比较,并将它们的子节点按对称顺序放入队列中。

2、代码实现

go
func isSymmetric(root *TreeNode) bool {
    if root == nil {
        return true
    }
    queue := []*TreeNode{root.Left, root.Right}
    for len(queue) > 0 {
        left, right := queue[0], queue[1]
        queue = queue[2:]
        if left == nil && right == nil {
            continue
        }
        if left == nil || right == nil {
            return false
        }
        if left.Val != right.Val {
            return false
        }
        queue = append(queue, left.Left, right.Right, left.Right, right.Left)
    }
    return true
}

3、复杂度分析

  • 时间复杂度:O(n),其中 n 是树中节点的数量。
  • 空间复杂度:O(n),队列中最多存储 n/2 个节点。

四、总结

方案时间复杂度空间复杂度说明
递归法O(n)O(n)代码简洁,但可能会出现栈溢出
迭代法O(n)O(n)需要额外的队列存储节点,但不会出现栈溢出

两种方案的时间复杂度相同,但递归法在空间复杂度上可能会更高,因为它需要使用栈空间。迭代法在空间复杂度上更优,但代码相对复杂。在实际应用中,可以根据具体情况选择使用哪种方法。

木川工作室 (微信:mcmc2024)