LeetCode 热题 HOT 100 (226. 翻转二叉树)

问题描述

给定一棵二叉树的根节点 root,要求翻转这棵二叉树,并返回其根节点。
例如:

  • 示例 1:
    输入:root = [4,2,7,1,3,6,9]
    输出:[4,7,2,9,6,3,1]

  • 示例 2:
    输入:root = [2,1,3]
    输出:[2,3,1]

  • 示例 3:
    输入:root = []
    输出:[]


第一部分:二叉树基础知识

1. 什么是二叉树?

二叉树是一种常见的数据结构,由多个**节点(Node)**构成。
每个节点包含三个部分:

  • 数据部分(val):存储这个节点的数值。
  • 左子节点(left):指向当前节点的左孩子。
  • 右子节点(right):指向当前节点的右孩子。

例如,下面是一棵简单的二叉树:

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

在这棵树中,根节点为 4,节点 4 的左子树是以 2 为根的子树,右子树是以 7 为根的子树。

2. Java 中如何表示二叉树

通常我们定义一个二叉树节点的类(TreeNode)如下:

public class TreeNode {
    int val;            // 节点的值
    TreeNode left;      // 左子节点
    TreeNode right;     // 右子节点

    // 默认构造方法
    TreeNode() {}

    // 构造方法:只传入节点值
    TreeNode(int val) { 
        this.val = val; 
    }

    // 构造方法:传入节点值和左右子节点
    TreeNode(int val, TreeNode left, TreeNode right) { 
        this.val = val; 
        this.left = left; 
        this.right = right; 
    }
}

这样,我们就可以用 TreeNode 类来构造和操作二叉树。


第二部分:翻转二叉树问题分析

1. 什么是翻转二叉树?

翻转二叉树也叫反转二叉树,它的意思是将二叉树中所有节点的左子树和右子树互换。
例如,原二叉树如下:

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

翻转后的二叉树应为:

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

2. 解题思路 —— 递归方法

递归是一种解决问题的方式,它将大问题拆分为相同形式的小问题。
翻转二叉树可以使用递归解决,基本思路如下:

  1. 递归终止条件:
    如果当前节点为空(null),直接返回 null
  2. 交换左右子节点:
    对于当前节点,将它的左子节点和右子节点进行互换。
  3. 递归调用:
    分别对左子树和右子树进行同样的翻转操作。

这个过程可以用以下伪代码表示:

function invertTree(node):
    if node == null:
        return null
    swap(node.left, node.right)
    invertTree(node.left)
    invertTree(node.right)
    return node

通过递归,每个节点都会交换它的左右孩子,从而实现整棵树的翻转。


第三部分:Java 代码实现

下面给出完整的 Java 代码,并在代码中添加详细注释,帮助你理解每一步操作:

public class Solution {
    public TreeNode invertTree(TreeNode root) {
        // 递归终止条件:如果当前节点为空,直接返回 null
        if (root == null) {
            return null;
        }
        
        // 保存当前节点的左子树
        TreeNode temp = root.left;
        // 将当前节点的左子树指向右子树
        root.left = root.right;
        // 将当前节点的右子树指向之前保存的左子树
        root.right = temp;
        
        // 递归翻转左子树
        invertTree(root.left);
        // 递归翻转右子树
        invertTree(root.right);
        
        // 返回当前节点,它现在是翻转后的子树的根
        return root;
    }
    
    // 主方法用于测试
    public static void main(String[] args) {
        /*
         构造示例二叉树:
                 4
                / \
               2   7
              / \ / \
             1  3 6  9
        */
        TreeNode node1 = new TreeNode(1);
        TreeNode node3 = new TreeNode(3);
        TreeNode node6 = new TreeNode(6);
        TreeNode node9 = new TreeNode(9);
        TreeNode node2 = new TreeNode(2, node1, node3);
        TreeNode node7 = new TreeNode(7, node6, node9);
        TreeNode root = new TreeNode(4, node2, node7);
        
        Solution sol = new Solution();
        TreeNode invertedRoot = sol.invertTree(root);
        
        // 打印翻转后的二叉树
        // 这里只简单地输出根节点的值,详细打印需要遍历整棵树
        System.out.println("翻转后的根节点值:" + invertedRoot.val);
        // 翻转后的树结构应为:
        //        4
        //       / \
        //      7   2
        //     / \ / \
        //    9  6 3  1
    }
}

代码解析

  1. 递归终止条件:

    if (root == null) {
        return null;
    }
    

    当遇到空节点时,直接返回 null

  2. 交换左右子节点:

    TreeNode temp = root.left;
    root.left = root.right;
    root.right = temp;
    

    这几行代码实现了当前节点左右子树的交换。

  3. 递归调用:

    invertTree(root.left);
    invertTree(root.right);
    

    对交换后的左子树和右子树分别进行同样的翻转操作。

  4. 返回当前节点:
    最后返回 root,表示当前子树(已经翻转)回到上一层递归。


第四部分:深入理解递归与二叉树

1. 递归基础

  • 递归是一种将问题分解为更小实例的求解方法。
  • 每个递归函数都必须有一个终止条件(本题中,当节点为 null 时)。
  • 递归调用过程中,每一层都会保存当前的状态,直到达到终止条件,然后返回结果,依次回溯。

2. 二叉树递归遍历

  • 二叉树的前序、中序、后序遍历都可以用递归轻松实现。
  • 本题中,我们通过递归将每个节点的左右子树翻转。这实际上是在做一个后序遍历
    先处理当前节点,再递归处理其左右子树。

3. 为什么递归适用于翻转二叉树?

  • 每个节点的操作都是相同的:交换左右孩子,然后对子树递归调用。
  • 这种“同质性”正是递归求解的典型场景。

第五部分:总结

  • 二叉树基础知识:
    了解二叉树的定义、节点组成以及如何在 Java 中表示二叉树。
  • 递归:
    理解递归的概念、终止条件和回溯过程,这对于翻转二叉树非常重要。
  • 翻转二叉树问题:
    翻转二叉树的核心在于对每个节点交换左右孩子,然后递归翻转左右子树。
  • Java 实现:
    提供了完整的代码示例,并通过主方法测试了翻转操作。

你可能感兴趣的:(LeetCode,HOT,100,leetcode,算法,职场和发展)