题目描述:
题目难度:简单
给你一棵二叉树的根节点 root
,翻转这棵二叉树,并返回其根节点。
示例 1:
输入:root = [4,2,7,1,3,6,9] 输出:[4,7,2,9,6,3,1]
示例 2:
输入:root = [2,1,3] 输出:[2,3,1]
示例 3:
输入:root = [] 输出:[]
提示:
- 树中节点数目范围在
[0, 100]
内 -100 <= Node.val <= 100
解题准备:
1.题意:题目要求把二叉树翻转,那么,什么是二叉树的翻转?
对于一棵树root,它的翻转是否仅仅是把左子节点变成右子节点,右子节点变成左子节点?显然不是。
按照题目示例1,我们可以发现,root的翻转,除了把左子节点变成右子节点,还把左子树也翻转了。也就是说,翻转一棵树root,需要把它的子孙也翻转。
2.基本操作:本题目属于技巧题,考察对二叉树迭代型的理解,基本不涉及增删改查。
3.基础原理:面对二叉树的题目,我们必须先考虑BFS或者DFS,这两个算法是解决二叉树的基础。
解题思路:
一般来说,想处理一棵二叉树,先考虑3种标准情况:
第一,【a,b,c】二叉树,也就是根节点a,左子节点b,右子节点c。
此时,翻转这棵树,只需改为【a,c,b】即可。
第二,【a,b,null】二叉树,也就是根节点a,左子节点b,右子节点为空。
此时,翻转这棵树,只需改为【a,null,b】即可。
第三,【a,null,b】二叉树,也就是根节点a,左子节点null,右子节点b。
此时,翻转这棵树,只需改为【a,b,null】即可。
对于“翻转”这个操作,我们可以将其概括为一步:
左子节点变为右子节点,右子节点变为左子节点。【也就是只剩一个标准情况】
问题来了,如果子树不止有根节点呢?比如【a,b,c,d】,即左子节点b,b有左子节点d。
我们的“一步”操作落空,不过,对于子树b,翻转b有几个操作?明显也是一步。
回到根节点a,翻转a,需要变成序列【a,c,b,null,null,null,d】,如何操作?
如果把3个null和d忽略,我们发现,这是一种标准二叉树的情况。
我们假设:想翻转某个节点,只需左右节点互换,然后让左右子节点再次翻转即可。
这满足递归性质。
即:左右子节点互换,并递归操作其子节点。
证明:标准二叉树翻转已知,假设root为根,其下有x个子孙节点。
如果到达最底层叶子节点,那么其不用翻转。
如果到达叶子节点的父节点,那么翻转左右节点,此时满足翻转的特征。
如果是倒数第3层,那么翻转左右节点,由于叶子节点的父节点已经翻转,满足翻转特征,因此倒数第3层理应满足特征。
如此迭代……
证明完毕。
解题难点分析:
难以理解的角度:先翻转左右子节点,然后从叶子节点出发,证明这个道理正确,这好像不对啊?
其实这只是思考的角度不同,我们知道,这个思路一共有2步:
第一,翻转左右节点
第二,左右子树翻转。
这两步会相互影响吗?
如果从上到下看,先翻转左右节点,再让左右子树翻转。
那么,翻转左右节点,其实不影响左右子树的翻转,因为在翻转后,左右子树没有变化。
如果从下往上走呢?先翻转左右子树,再翻转左右节点?
左右子树的翻转,最终一定落实到叶子节点的父节点,然后依次向上翻转,最终到达根节点。这满足我们证明的步骤,没有问题。
代码:
class Solution {
public TreeNode invertTree(TreeNode root) {
// 叶子节点不处理
if(root==null){
return null;
}
// 翻转左右子节点
TreeNode temp=root.right;
root.right=root.left;
root.left=temp;
// 让子节点进行翻转
invertTree(root.left);
invertTree(root.right);
return root;
}
}
以上内容即我想分享的关于力扣热题26的一些知识。
我是蚊子码农,如有补充,欢迎在评论区留言。个人也是初学者,知识体系可能没有那么完善,希望各位多多指正,谢谢大家。