【LeetCode】226.翻转二叉树

leetcode

 

二叉树翻转规则

镜像翻转每个节点的左右子树,操作规则如下:

  1. 交换当前节点的左右子节点

  2. 递归翻转左子树

  3. 递归翻转右子树

 


示例

原始二叉树:

     4
   /   \
  2     7
 / \   / \
1   3 6   9

翻转后:

     4
   /   \
  7     2
 / \   / \
9   6 3   1

 


Go 递归实现

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func invertTree(root *TreeNode) *TreeNode {
    if root == nil {
        return nil
    }
    // 交换左右子树
    root.Left, root.Right = root.Right, root.Left
    // 递归翻转子树
    invertTree(root.Left)
    invertTree(root.Right)
    return root
}

 


Go 迭代实现(层序遍历)

func invertTree(root *TreeNode) *TreeNode {
    if root == nil {
        return nil
    }
    
    queue := []*TreeNode{root}
    for len(queue) > 0 {
        node := queue[0]
        queue = queue[1:]
        
        // 交换当前节点的左右子节点
        node.Left, node.Right = node.Right, node.Left
        
        // 将子节点加入队列
        if node.Left != nil {
            queue = append(queue, node.Left)
        }
        if node.Right != nil {
            queue = append(queue, node.Right)
        }
    }
    return root
}

 


核心思路

  1. 递归法

    • 终止条件:当前节点为空时返回

    • 操作顺序:先交换左右子节点,再递归处理左右子树

    • 时间复杂度 O(n):每个节点访问一次

    • 空间复杂度 O(h):h 为树高(递归栈深度)

  2. 迭代法

    • 使用队列层序遍历

    • 每次处理节点时交换其左右子树

    • 时间复杂度 O(n)

    • 空间复杂度 O(n)(队列最大存储节点数)

 


关键点

  • 交换操作不可逆:翻转是永久修改原树结构

  • 适用场景:需要镜像树结构的场景(如对称性判断前的预处理)

  • 空节点处理:遇到空节点直接跳过,无需操作

 


测试示例

func main() {
    // 构造示例树
    root := &TreeNode{Val:4}
    root.Left = &TreeNode{Val:2}
    root.Right = &TreeNode{Val:7}
    root.Left.Left = &TreeNode{Val:1}
    root.Left.Right = &TreeNode{Val:3}
    root.Right.Left = &TreeNode{Val:6}
    root.Right.Right = &TreeNode{Val:9}

    // 翻转并验证
    inverted := invertTree(root)
    printTree(inverted) // 应输出层序:4,7,2,9,6,3,1
}

// 辅助函数:层序打印二叉树
func printTree(root *TreeNode) {
    if root == nil {
        fmt.Println("nil")
        return
    }

    var result []string
    queue := []*TreeNode{root}

    for len(queue) > 0 {
        node := queue[0]   // 取出队列头部节点
        queue = queue[1:]  // 移除已处理节点

        result = append(result, fmt.Sprintf("%d", node.Val))

        // 将非空子节点加入队列
        if node.Left != nil {
            queue = append(queue, node.Left)
        }
        if node.Right != nil {
            queue = append(queue, node.Right)
        }
    }

    fmt.Println(strings.Join(result, ","))
}

 

posted @ 2025-03-11 13:24  云隙之间  阅读(32)  评论(0)    收藏  举报