算法题解记录26+++翻转二叉树(百日筑基)

题目描述:

        题目难度:简单

        给你一棵二叉树的根节点 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的一些知识。

        我是蚊子码农,如有补充,欢迎在评论区留言。个人也是初学者,知识体系可能没有那么完善,希望各位多多指正,谢谢大家。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值