![5c236f1a5e1bd0b7af9e6a47e56d6003.png](https://i-blog.csdnimg.cn/blog_migrate/05e222598ae1eec01aa6132572ed519e.jpeg)
No.226 反转二叉树
已知一个二叉树,我们希望它的左右子树位置交换,变成一个新的二叉树。如下图所示:
![cc3d5132bbd70ce619aac57edff990ca.png](https://i-blog.csdnimg.cn/blog_migrate/0c4b07c7dd062681c996b511bb0e20cd.png)
解题思路:
我们需要交换所有节点的左右子节点来解决此问题。我们可以用递归的方法把每个节点当初一个根节点来交换它的左右子节点。
我们也可以用迭代的方法来解决这个问题。例如 BFS和DFS方法。首先,我们创建了一个队列或者栈来存储其左子节点和右子节点尚未交换的节点。 初始状态时,只有根在队列或者栈中。 只要队列或者栈不为空,就从队列或者栈中删除下一个节点,交换其左右子节点,然后将子节点添加到队列或者栈中。 空节点不会添加到队列或者栈中。 最终,队列或者栈将为空,所有子节点都将交换,然后我们返回原始根。
第一种方法:递归
![9ae79c9961be2eca8af35c42b38a0af3.png](https://i-blog.csdnimg.cn/blog_migrate/a5efec228ad0bda44df962ead18ede6d.png)
测试:
![0145ed2877fab5ba24bac4cee7d8993b.png](https://i-blog.csdnimg.cn/blog_migrate/5a2da41023d1e886a873210dcae7caa0.png)
![93cae7791e59bb9fa83ca92b5d3408af.png](https://i-blog.csdnimg.cn/blog_migrate/3484b282a865a1e375223e06a73af214.png)
从上图的迭代的测试结果可以看出,在数组中表示左右子树均进行反转,满足题目的要求。
如果我们没有同时对左右子树进行交换就会出错,出现左右子树一样的情况,因为我们交换有了先后顺利,后面的交换会受到前面的交换的影响。
错误示范:
我们先后交换左右子节点
![3421815a4504660ef9043e1b0269b13e.png](https://i-blog.csdnimg.cn/blog_migrate/e1d9e2427dcbb4ae98c9cb30b8034653.png)
我们将得到左右子树一样的结果
![7fb0ad8250b4b39b4fe833d273e9bf6b.png](https://i-blog.csdnimg.cn/blog_migrate/2c0e1a7f5e87116296f98ab271a88e0b.png)
第二种方法: BFS 宽度优先法
![c1853b12895bd7c0b6e5d3df4efe3041.png](https://i-blog.csdnimg.cn/blog_migrate/ba12eb5d2e8d712c43b58430cd0e3df5.jpeg)
根据两种方法的特点,我们用队列来表示宽度优先,用栈来表示深度优先,队列是先进先出,栈是先进后出。 在BFS方法的code里,我们先定义一个队列,然后同时交换节点的左右子节点,交换后再加到队列中。
测试:
![eb4090a07f5cb94c9c6a3b989551f5e3.png](https://i-blog.csdnimg.cn/blog_migrate/c0183e93a3e686606be1ead7d8ebd99b.png)
从测试结果可以看出,运行速度比递归方法更快,满足所有左右子树反转的要求。
第三种方法:DFS 深度优先
![4f8b7129f9215232805f2cd884d9b79d.png](https://i-blog.csdnimg.cn/blog_migrate/78156850f53ee1c0f395d20ff882b962.jpeg)
同理,用深度优先算法时,我们先用栈表示根,然后同时交换根的左右子节点,交换后加入到栈中,最后得到一个交换所有左右子树的新树。
小结:本题是简单反转二叉树,我们采用了递归和迭代两种方法来解决此问题。在递归的方法解决此问题时,我们可以发现代码是简单清晰的,需要注意的是,需要同时左右子树,以确保左右子树一起变,不能有先后顺序,例如写成先交换左子树再交换右子树的形式就会出错,可能得到左右子树都一致的错误结果。复杂度分析,由于树中的每个节点仅被访问一次,因此时间复杂度为O(n),其中 n 是树中的节点数。
后两种方法BFS和DFS均属于迭代方法来解决此问题,比递归方法更快,但是需要借助队列和栈的特点,且代码没有递归的简洁。由于树中的每个节点仅被访问/添加到队列或者栈一次,因此时间复杂度为O(n),其中 n 是树中的节点数。
欢迎查看Leecode学习总结其他文章:
Simone:Leecode每日刷题——合并有序链表
Simone:Leecode每日刷题——反转链表
Simone:Leecode每日刷题——反转二叉树
Simone:Leecode 每日刷题 — 合并两个二叉树