一篇学会二叉树的镜像

开发 前端
二叉树镜像定义: 对于二叉树中任意节点 root ,设其左 / 右子节点分别为 left, right;则在二叉树的镜像中的对应 root节点,其左 / 右子节点分别为 right, left 。

 [[437293]]

本文转载自微信公众号「程序员千羽」,作者程序员千羽。转载本文请联系程序员千羽公众号。

Leetcode : https://leetcode-cn.com/problems/er-cha-shu-de-jing-xiang-lcof

“GitHub : https://github.com/nateshao/leetcode/blob/main/algo-notes/src/main/java/com/nateshao/sword_offer/topic_21_mirrorTree/Solution.java

 二叉树的镜像

“题目描述 :请完成一个函数,输入一个二叉树,该函数输出它的镜像。例如输入:

    4 
   /   \ 
  2     7 
 / \   / \ 
1   3 6   9 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

镜像输出:

      4 
    /   \ 
   7     2 
 / \   / \ 
9   6 3   1 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

示例 1:

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

限制:0 <= 节点个数 <= 1000

分析

二叉树镜像定义: 对于二叉树中任意节点 root ,设其左 / 右子节点分别为 left, right;则在二叉树的镜像中的对应 root节点,其左 / 右子节点分别为 right, left 。

方法一:递归法

根据二叉树镜像的定义,考虑递归遍历(dfs)二叉树,交换每个节点的左 / 右子节点,即可生成二叉树的镜像。

递归解析:

终止条件: 当节点 root为空时(即越过叶节点),则返回 null ;

递推工作:

初始化节点tmp,用于暂存root的左子节点; .

开启递归右子节点mirrorTree(root.right),并将返回值作为root的左子节点。

开启递归左子节点mirrorTree(tmp) ,并将返回值作为root的右子节点。

返回值:返回当前节点root ;

“Q:为何需要暂存root的左子节点? A:在递归右子节 点“root.left = mirrorTree(root.right);"执行完毕后,root.left 的值已经发生改变,此时递归左子节点mirrorTree(root.left)则会出问题。

复杂度分析:

  • 时间复杂度0(N) : 其中N为二叉树的节点数量,建立二叉树镜像需要遍历树的所有节点,占用O(N)时间。
  • 空间复杂度O(N): 最差情况下(当二叉树退化为链表),递归时系统需使用O(N)大小的栈空间。
package com.nateshao.sword_offer.topic_21_mirrorTree; 
 
import java.util.Stack; 
 
/** 
 * @date Created by 邵桐杰 on 2021/11/24 22:48 
 * @微信公众号 程序员千羽 
 * @个人网站 www.nateshao.cn 
 * @博客 https://nateshao.gitee.io 
 * @GitHub https://github.com/nateshao 
 * @Gitee https://gitee.com/nateshao 
 * Description: 剑指 Offer 27. 二叉树的镜像 
 */ 
public class Solution { 
    /** 
     * 递归 
     * 
     * @param root 
     * @return 
     */ 
    public TreeNode mirrorTree(TreeNode root) { 
        if (root == nullreturn null
        TreeNode node = root.left
        root.left = mirrorTree(root.right); 
        root.right = mirrorTree(node); 
        return root; 
    } 
 
    /** 
     * 解法一:递归,时间复杂度:O(n),空间复杂度:O(n) 
     * 
     * @param root 
     * @return 
     */ 
    public boolean isSymmetric(TreeNode root) { 
        if (root == nullreturn true
        return isMirror(root.left, root.right); 
    } 
 
    private boolean isMirror(TreeNode leftNode, TreeNode rightNode) { 
        if (leftNode == null && rightNode == nullreturn true
        if (leftNode == null || rightNode == nullreturn false
 
        return leftNode.val == rightNode.val && isMirror(leftNode.left, rightNode.right) && isMirror(leftNode.right, rightNode.left); 
    } 
 
    public class TreeNode { 
        int val; 
        TreeNode left
        TreeNode right
 
        TreeNode(int x) { 
            val = x; 
        } 
    } 
 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.

方法二:辅助栈(或队列)

利用栈(或队列)遍历树的所有节点node,并交换每个node的左/右子节点。

算法流程:

  • 特例处理: 当root为空时,直接返回null ;
  • 初始化: 栈(或队列),本文用栈,并加入根节点root 。
  • 循环交换: 当栈 stack为控时跳出;
    • 出栈:记为node ;
    • 添加子节点:将node左和右子节点入栈;
    • 交换:交换node的左1右子节点。
  • 返回值:返回根节点root。

复杂度分析:

  • 时间复杂度0(N) :其中N为二叉树的节点数量,建立二叉树镜像需要遍历树的所有节点,占用O(N)时间。
  • 空间复杂度O(N) :如下图所示,最差情况下,栈stack最多同时存储N+1/2个节点,占用O(N)额外空间。

package com.nateshao.sword_offer.topic_21_mirrorTree; 
 
import java.util.Stack; 
 
/** 
 * @date Created by 邵桐杰 on 2021/11/24 22:48 
 * @微信公众号 程序员千羽 
 * @个人网站 www.nateshao.cn 
 * @博客 https://nateshao.gitee.io 
 * @GitHub https://github.com/nateshao 
 * @Gitee https://gitee.com/nateshao 
 * Description: 剑指 Offer 27. 二叉树的镜像 
 */ 
public class Solution { 
    /** 
     * 栈 
     * 
     * @param root 
     * @return 
     */ 
    public TreeNode mirrorTree1(TreeNode root) { 
        if (root == nullreturn null
        Stack<TreeNode> stack = new Stack<TreeNode>() {{ 
            add(root); 
        }}; 
        while (!stack.isEmpty()) { 
            TreeNode node = stack.pop(); 
            if (node.left != null) stack.add(node.left); 
            if (node.right != null) stack.add(node.right); 
            TreeNode tmp = node.left
            node.left = node.right
            node.right = tmp; 
        } 
        return root; 
    } 
    /** 
     * 解法二:迭代,时间复杂度:O(n),空间复杂度:O(n) 
     * 
     * @param root 
     * @return 
     */ 
    public boolean isSymmetric2(TreeNode root) { 
        Stack<TreeNode> stack = new Stack<>(); 
        stack.push(root); 
        stack.push(root); 
        while (!stack.isEmpty()) { 
            TreeNode t1 = stack.pop(); 
            TreeNode t2 = stack.pop(); 
            if (t1 == null && t2 == nullcontinue
            if (t1 == null || t2 == nullreturn false
            if (t1.val != t2.val) return false
 
            stack.push(t1.left); 
            stack.push(t2.right); 
            stack.push(t1.right); 
            stack.push(t2.left); 
        } 
        return true
    } 
 
    public class TreeNode { 
        int val; 
        TreeNode left
        TreeNode right
 
        TreeNode(int x) { 
            val = x; 
        } 
    } 
 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.

参考链接:https://leetcode-cn.com/problems/er-cha-shu-de-jing-xiang-lcof/solution/mian-shi-ti-27-er-cha-shu-de-jing-xiang-di-gui-fu-

 

责任编辑:武晓燕 来源: 程序员千羽
相关推荐

2021-12-17 14:26:58

二叉树节点数量

2022-07-27 07:45:53

二叉树镜像函数

2020-04-27 07:05:58

二叉树左子树右子树

2021-05-06 17:46:30

二叉树数据结构

2021-04-19 07:47:42

数据结构二叉树Tree

2021-04-20 08:37:14

数据结构二叉树

2021-04-28 20:12:27

数据结构创建

2022-10-26 23:58:02

二叉树数组算法

2021-03-17 08:19:22

二叉树LeetCode

2013-07-15 16:35:55

二叉树迭代器

2021-08-27 11:36:44

二叉树回溯节点

2021-09-29 10:19:00

算法平衡二叉树

2020-09-23 18:25:40

算法二叉树多叉树

2022-11-06 19:43:10

二叉树指针节点

2018-03-15 08:31:57

二叉树存储结构

2021-12-05 18:25:12

二叉树路径节点

2021-10-12 09:25:11

二叉树树形结构

2021-09-15 07:56:32

二叉树层次遍历

2022-10-12 23:25:17

二叉树父节点根节点

2021-03-22 08:23:29

LeetCode二叉树节点
点赞
收藏

51CTO技术栈公众号