434,剑指 Offer

Stella981
• 阅读 693

434,剑指 Offer

The more you know who you are and what you want, the less you let things upset you.

你越了解自己以及自己想要的东西,你就越不会被外界困扰。

问题描述

请完成一个函数,输入一个二叉树,该函数输出它的镜像。

例如输入:

4

/   \

2     7

/ \   / \

1   3 6   9

镜像输出:

4

/   \

7     2

/ \   / \

9   6 3   1

示例 1:

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

输出:[4,7,2,9,6,3,1]

限制:

0 <= 节点个数 <= 1000

BFS解决

之前讲373,数据结构-6,树的时候,提到过二叉树的广度优先搜索,就是一层一层的访问,像下面这样

434,剑指 Offer

二叉树的BFS代码如下

 1public static void treeBFS(TreeNode root) { 2    //如果为空直接返回 3    if (root == null) 4        return; 5    //队列 6    Queue<TreeNode> queue = new LinkedList<>(); 7    //首先把根节点加入到队列中 8    queue.add(root); 9    //如果队列不为空就继续循环10    while (!queue.isEmpty()) {11        //poll方法相当于移除队列头部的元素12        TreeNode node = queue.poll();13        //打印当前节点14        System.out.println(node.val);15        //如果当前节点的左子树不为空,就把左子树16        //节点加入到队列中17        if (node.left != null)18            queue.add(node.left);19        //如果当前节点的右子树不为空,就把右子树20        //节点加入到队列中21        if (node.right != null)22            queue.add(node.right);23    }24}

这题要求的是输出二叉树的镜像,就是每一个节点的左右子节点进行交换,随便画个二叉树看一下

434,剑指 Offer

我们需要遍历每一个节点,然后交换他的两个子节点,一直循环下去,直到所有的节点都遍历完为止,代码如下

 1public TreeNode mirrorTree(TreeNode root) { 2    //如果为空直接返回 3    if (root == null) 4        return null; 5    //队列 6    final Queue<TreeNode> queue = new LinkedList<>(); 7    //首先把根节点加入到队列中 8    queue.add(root); 9    while (!queue.isEmpty()) {10        //poll方法相当于移除队列头部的元素11        TreeNode node = queue.poll();12        //交换node节点的两个子节点13        TreeNode left = node.left;14        node.left = node.right;15        node.right = left;16        //如果当前节点的左子树不为空,就把左子树17        //节点加入到队列中18        if (node.left != null) {19            queue.add(node.left);20        }21        //如果当前节点的右子树不为空,就把右子树22        //节点加入到队列中23        if (node.right != null) {24            queue.add(node.right);25        }26    }27    return root;28}

DFS解决

无论是BFS还是DFS都会访问到每一个节点,访问每个节点的时候交换他的左右子节点,直到所有的节点都访问完为止,代码如下

 1public TreeNode mirrorTree(TreeNode root) {//DFS 2    //如果为空直接返回 3    if (root == null) 4        return null; 5    //栈 6    Stack<TreeNode> stack = new Stack<>(); 7    //根节点压栈 8    stack.push(root); 9    //如果栈不为空就继续循环10    while (!stack.empty()) {11        //出栈12        TreeNode node = stack.pop();13        //子节点交换14        TreeNode temp = node.left;15        node.left = node.right;16        node.right = temp;17        //左子节点不为空入栈18        if (node.left != null)19            stack.push(node.left);20        //右子节点不为空入栈21        if (node.right != null)22            stack.push(node.right);23    }24    return root;25}

中序遍历解决

这题其实解法比较多,只要访问他的每一个节点,然后交换子节点即可,我们知道二叉树不光有BFS和DFS访问顺序,而且还有前序遍历,中序遍历和后续遍历等,不管哪种访问方式,只要能把所有节点都能访问一遍然后交换子节点就能解决,我们这里就以中序遍历来看下,前序和后序就不在看了。在373,数据结构-6,树中,提到二叉树中序遍历的非递归写法如下

 1public static void inOrderTraversal(TreeNode tree) { 2    Stack<TreeNode> stack = new Stack<>(); 3    while (tree != null || !stack.isEmpty()) { 4        while (tree != null) { 5            stack.push(tree); 6            tree = tree.left; 7        } 8        if (!stack.isEmpty()) { 9            tree = stack.pop();10            System.out.println(tree.val);11            tree = tree.right;12        }13    }14}

我们来对他改造一下,就是在访问每个节点的时候交换,代码如下

 1public static TreeNode mirrorTree(TreeNode root) { 2    //如果为空直接返回 3    if (root == null) 4        return null; 5    Stack<TreeNode> stack = new Stack<>(); 6    TreeNode node = root; 7    while (node != null || !stack.isEmpty()) { 8        while (node != null) { 9            stack.push(node);10            node = node.left;11        }12        if (!stack.isEmpty()) {13            node = stack.pop();14            //子节点交换15            TreeNode temp = node.left;16            node.left = node.right;17            node.right = temp;18            //注意这里以前是node.right,因为上面已经交换了19            //,所以这里要改为node.left20            node = node.left;21        }22    }23    return root;24}

递归方式解决

二叉树中序遍历的递归代码如下

1public void inOrderTraversal(TreeNode node) {2    if (node == null)3        return;4    inOrderTraversal(node.left);5    System.out.println(node.val);6    inOrderTraversal(node.right);7}

上面说了,只要能访问二叉树的每一个节点,然后交换左右子节点就行了,这里就以二叉树中序遍历递归的方式来看下

 1public TreeNode mirrorTree(TreeNode root) { 2    if (root == null) 3        return null; 4    mirrorTree(root.left); 5    //子节点交换 6    TreeNode temp = root.left; 7    root.left = root.right; 8    root.right = temp; 9    //上面交换过了,这里root.right要变成root.left10    mirrorTree(root.left);11    return root;12}

再来看一个后续遍历的

1public TreeNode mirrorTree(TreeNode root) {2    if (root == null)3        return null;4    TreeNode left = mirrorTree(root.left);5    TreeNode right = mirrorTree(root.right);6    root.left = right;7    root.right = left;8    return root;9}

总结

这题没什么难度,但解法比较多,主要是因为二叉树的遍历方式比较多,如果每一种方式递归和非递归都写的话就更多了。

434,剑指 Offer

433,剑指 Offer-树的子结构

414,剑指 Offer-重建二叉树

403,验证二叉搜索树

401,删除二叉搜索树中的节点

434,剑指 Offer

长按上图,识别图中二维码之后即可关注。

如果觉得有用就点个"赞"吧

本文分享自微信公众号 - 数据结构和算法(sjjghsf)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Wesley13 Wesley13
3年前
剑指Offer
题目:输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。分析:将数字和1先做与运算,然后将1右移一位,现在是判断数字的第二位是不是1,这样循环的做下去即可。也可以转换成字符串再统计1的个数。程序:CclassSolution{public:intN
Stella981 Stella981
3年前
Postman 使用方法详细介绍
1,下载安装:https://www.getpostman.com/apps2,打开Postman,如图所示:!(https://oscimg.oschina.net/oscnet/00f434cd831f2f74fea6f6d7b86bc46a751.png)3,创建一个接口项目!(https://oscimg.oschina.
可莉 可莉
3年前
2021 最顶级 React 组件库推荐
点上方蓝字关注公众号「前端从进阶到入院」作者丨MaxRozen译者丨王强策划丨小智AntDesign!(https://oscimg.oschina.net/oscnet/a85c35f23bd04e5da6a1e5e68a24119b.png)项目链接:AntDesignh
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
35岁是技术人的天花板吗?
35岁是技术人的天花板吗?我非常不认同“35岁现象”,人类没有那么脆弱,人类的智力不会说是35岁之后就停止发展,更不是说35岁之后就没有机会了。马云35岁还在教书,任正非35岁还在工厂上班。为什么技术人员到35岁就应该退役了呢?所以35岁根本就不是一个问题,我今年已经37岁了,我发现我才刚刚找到自己的节奏,刚刚上路。
Stella981 Stella981
3年前
432,剑指 Offer
!(https://oscimg.oschina.net/oscnet/f76dba60b9024af796d7f00bf6be5334.png)Successisstumblingfromfailuretofailurewithnolossofenthusiasm.成功是在失败中摸索,同时不失去热情。