一篇学会二叉树的镜像

开发 前端
二叉树镜像定义: 对于二叉树中任意节点 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

 二叉树的镜像

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

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

镜像输出:

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

示例 1:

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

限制: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)大小的栈空间。
  1. package com.nateshao.sword_offer.topic_21_mirrorTree; 
  2.  
  3. import java.util.Stack; 
  4.  
  5. /** 
  6.  * @date Created by 邵桐杰 on 2021/11/24 22:48 
  7.  * @微信公众号 程序员千羽 
  8.  * @个人网站 www.nateshao.cn 
  9.  * @博客 https://nateshao.gitee.io 
  10.  * @GitHub https://github.com/nateshao 
  11.  * @Gitee https://gitee.com/nateshao 
  12.  * Description: 剑指 Offer 27. 二叉树的镜像 
  13.  */ 
  14. public class Solution { 
  15.     /** 
  16.      * 递归 
  17.      * 
  18.      * @param root 
  19.      * @return 
  20.      */ 
  21.     public TreeNode mirrorTree(TreeNode root) { 
  22.         if (root == nullreturn null
  23.         TreeNode node = root.left
  24.         root.left = mirrorTree(root.right); 
  25.         root.right = mirrorTree(node); 
  26.         return root; 
  27.     } 
  28.  
  29.     /** 
  30.      * 解法一:递归,时间复杂度:O(n),空间复杂度:O(n) 
  31.      * 
  32.      * @param root 
  33.      * @return 
  34.      */ 
  35.     public boolean isSymmetric(TreeNode root) { 
  36.         if (root == nullreturn true
  37.         return isMirror(root.left, root.right); 
  38.     } 
  39.  
  40.     private boolean isMirror(TreeNode leftNode, TreeNode rightNode) { 
  41.         if (leftNode == null && rightNode == nullreturn true
  42.         if (leftNode == null || rightNode == nullreturn false
  43.  
  44.         return leftNode.val == rightNode.val && isMirror(leftNode.left, rightNode.right) && isMirror(leftNode.right, rightNode.left); 
  45.     } 
  46.  
  47.     public class TreeNode { 
  48.         int val; 
  49.         TreeNode left
  50.         TreeNode right
  51.  
  52.         TreeNode(int x) { 
  53.             val = x; 
  54.         } 
  55.     } 
  56.  

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

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

算法流程:

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

复杂度分析:

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

  1. package com.nateshao.sword_offer.topic_21_mirrorTree; 
  2.  
  3. import java.util.Stack; 
  4.  
  5. /** 
  6.  * @date Created by 邵桐杰 on 2021/11/24 22:48 
  7.  * @微信公众号 程序员千羽 
  8.  * @个人网站 www.nateshao.cn 
  9.  * @博客 https://nateshao.gitee.io 
  10.  * @GitHub https://github.com/nateshao 
  11.  * @Gitee https://gitee.com/nateshao 
  12.  * Description: 剑指 Offer 27. 二叉树的镜像 
  13.  */ 
  14. public class Solution { 
  15.     /** 
  16.      * 栈 
  17.      * 
  18.      * @param root 
  19.      * @return 
  20.      */ 
  21.     public TreeNode mirrorTree1(TreeNode root) { 
  22.         if (root == nullreturn null
  23.         Stack<TreeNode> stack = new Stack<TreeNode>() {{ 
  24.             add(root); 
  25.         }}; 
  26.         while (!stack.isEmpty()) { 
  27.             TreeNode node = stack.pop(); 
  28.             if (node.left != null) stack.add(node.left); 
  29.             if (node.right != null) stack.add(node.right); 
  30.             TreeNode tmp = node.left
  31.             node.left = node.right
  32.             node.right = tmp; 
  33.         } 
  34.         return root; 
  35.     } 
  36.     /** 
  37.      * 解法二:迭代,时间复杂度:O(n),空间复杂度:O(n) 
  38.      * 
  39.      * @param root 
  40.      * @return 
  41.      */ 
  42.     public boolean isSymmetric2(TreeNode root) { 
  43.         Stack<TreeNode> stack = new Stack<>(); 
  44.         stack.push(root); 
  45.         stack.push(root); 
  46.         while (!stack.isEmpty()) { 
  47.             TreeNode t1 = stack.pop(); 
  48.             TreeNode t2 = stack.pop(); 
  49.             if (t1 == null && t2 == nullcontinue
  50.             if (t1 == null || t2 == nullreturn false
  51.             if (t1.val != t2.val) return false
  52.  
  53.             stack.push(t1.left); 
  54.             stack.push(t2.right); 
  55.             stack.push(t1.right); 
  56.             stack.push(t2.left); 
  57.         } 
  58.         return true
  59.     } 
  60.  
  61.     public class TreeNode { 
  62.         int val; 
  63.         TreeNode left
  64.         TreeNode right
  65.  
  66.         TreeNode(int x) { 
  67.             val = x; 
  68.         } 
  69.     } 
  70.  

参考链接: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

二叉树存储结构

2022-06-30 22:53:18

数据结构算法

2021-12-05 18:25:12

二叉树路径节点

2021-09-15 07:56:32

二叉树层次遍历

2021-10-12 09:25:11

二叉树树形结构

2022-10-12 23:25:17

二叉树父节点根节点
点赞
收藏

51CTO技术栈公众号