算法刷题 - 二叉树(翻转二叉树)

134 阅读2分钟

原题链接

LeetCode 226 翻转二叉树

题目描述

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。

方法

思路 01 - 递归

  • 前序遍历使用递归实现,按照根左右遍历所有节点
  • 翻转所有非叶子节点子节点
  • 递归返回条件: 节点为空

代码

class Solution {

    /*
     * 前序遍历:
     * 递归终止条件: 节点为空
     */
    public TreeNode invertTree(TreeNode root) {
        // 检查输入
        if (root == null || (root.left == null && root.right == null)) {
            return root;
        }
        preOrderReverse(root);
        return root;
    }

    public void preOrderReverse(TreeNode node) {
        if (node == null) // 叶子节点的子节点为空
            return;
        swap(node); // 翻转所有非叶子节点子节点
        preOrderReverse(node.left); // 左
        preOrderReverse(node.right); // 右
    }

    private void swap(TreeNode node) {
        if (node.left == null && node.right == null)
            return;
        TreeNode tmp = node.left;
        node.left = node.right;
        node.right = tmp;
    }
}

执行结果

  • 时间复杂度: O(N)
  • 空间复杂度: O(N)

思路 02 - 辅助栈

  • 使用栈进行层次遍历,并交换每个子树的左右子节点。
  • 如果根节点非空,将其压入栈中。
  • 依次将非空的左、右子节点压入栈中以继续遍历。
  • 利用临时变量暂存节点信息,实现左右子节点值的互换。

代码

class Solution {

    public TreeNode mirrorTree(TreeNode root) {
        if (null == root)
            return null;

        // 借助栈实现遍历树的各个叶子结点
        Deque<TreeNode> stack = new LinkedList<>();
        stack.push(root); // 记录根节点

        while (!stack.isEmpty()) {
            TreeNode top = stack.pop(); // 积累当前结点的左右子节点
            if (top.left != null)
                stack.push(top.left);
            if (top.right != null)
                stack.push(top.right);
            TreeNode tmp = top.left;   //更新当前结点的左右节点值
            top.left = top.right;
            top.right = tmp;
        }
        return root;
    }
}

执行结果

  • 时间复杂度: O(N)
  • 空间复杂度: O(N)

思路 02 - 广度优先

  • 借助队列,如果出队节点左右节点不为空;将其入队
  • 每个出队节点交换左右指针

代码

class Solution {
    public TreeNode invertTree(TreeNode root) {
        // 检查输入 - 如果树节点为空
        if (root == null || root.left == null && root.right == null) {
            return root;
        }
        // 层序遍历,借助队
        Deque<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            TreeNode peek = queue.poll();
            swap(peek);
            // 如果左右节点不为空,将其入队
            if (peek.left != null)
                queue.offer(peek.left);
            if (peek.right != null)
                queue.offer(peek.right);
        }
        return root;
    }

    // 交换左右节点
    public void swap(TreeNode node) {
        TreeNode tmp = node.left;
        node.left = node.right;
        node.right = tmp;
    }
}

执行结果

  • 时间复杂度: O(N)
  • 空间复杂度: O(N)