c++ 删除二叉树的子树_Leecode每日刷题——反转二叉树

5c236f1a5e1bd0b7af9e6a47e56d6003.png

No.226 反转二叉树

已知一个二叉树,我们希望它的左右子树位置交换,变成一个新的二叉树。如下图所示:

cc3d5132bbd70ce619aac57edff990ca.png

解题思路:

我们需要交换所有节点的左右子节点来解决此问题。我们可以用递归的方法把每个节点当初一个根节点来交换它的左右子节点。

我们也可以用迭代的方法来解决这个问题。例如 BFS和DFS方法。首先,我们创建了一个队列或者栈来存储其左子节点和右子节点尚未交换的节点。 初始状态时,只有根在队列或者栈中。 只要队列或者栈不为空,就从队列或者栈中删除下一个节点,交换其左右子节点,然后将子节点添加到队列或者栈中。 空节点不会添加到队列或者栈中。 最终,队列或者栈将为空,所有子节点都将交换,然后我们返回原始根。

第一种方法:递归

9ae79c9961be2eca8af35c42b38a0af3.png

测试:

0145ed2877fab5ba24bac4cee7d8993b.png

93cae7791e59bb9fa83ca92b5d3408af.png

从上图的迭代的测试结果可以看出,在数组中表示左右子树均进行反转,满足题目的要求。

如果我们没有同时对左右子树进行交换就会出错,出现左右子树一样的情况,因为我们交换有了先后顺利,后面的交换会受到前面的交换的影响。

错误示范:

我们先后交换左右子节点

3421815a4504660ef9043e1b0269b13e.png

我们将得到左右子树一样的结果

7fb0ad8250b4b39b4fe833d273e9bf6b.png

第二种方法: BFS 宽度优先法

c1853b12895bd7c0b6e5d3df4efe3041.png

根据两种方法的特点,我们用队列来表示宽度优先,用栈来表示深度优先,队列是先进先出,栈是先进后出。 在BFS方法的code里,我们先定义一个队列,然后同时交换节点的左右子节点,交换后再加到队列中。

测试:

eb4090a07f5cb94c9c6a3b989551f5e3.png

从测试结果可以看出,运行速度比递归方法更快,满足所有左右子树反转的要求。

第三种方法:DFS 深度优先

4f8b7129f9215232805f2cd884d9b79d.png

同理,用深度优先算法时,我们先用栈表示根,然后同时交换根的左右子节点,交换后加入到栈中,最后得到一个交换所有左右子树的新树。

小结:本题是简单反转二叉树,我们采用了递归和迭代两种方法来解决此问题。在递归的方法解决此问题时,我们可以发现代码是简单清晰的,需要注意的是,需要同时左右子树,以确保左右子树一起变,不能有先后顺序,例如写成先交换左子树再交换右子树的形式就会出错,可能得到左右子树都一致的错误结果。复杂度分析,由于树中的每个节点仅被访问一次,因此时间复杂度为O(n),其中 n 是树中的节点数。

后两种方法BFS和DFS均属于迭代方法来解决此问题,比递归方法更快,但是需要借助队列和栈的特点,且代码没有递归的简洁。由于树中的每个节点仅被访问/添加到队列或者栈一次,因此时间复杂度为O(n),其中 n 是树中的节点数。

欢迎查看Leecode学习总结其他文章:

Simone:Leecode每日刷题——合并有序链表

Simone:Leecode每日刷题——反转链表

Simone:Leecode每日刷题——反转二叉树

Simone:Leecode 每日刷题 — 合并两个二叉树

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值