每日一题算法:2020年8月2日 [二叉树展开为链表] flatten

2020年8月2日 二叉树展开为链表 flatten

在这里插入图片描述

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public void flatten(TreeNode root) {
        
    }
}

解题思路:

首先解释一下,题目中所提到的原地展开是什么意思。

原地算法的特点就在于,他是空间复杂度为0。不使用其他的空间,只是内部的指针互相转换来实现的算法。

比如冒泡算法就是一种经典的原地算法,在自己数组上操作,不使用额外的空间。

再看题中的排序方式,应该不难发现这是属于中序遍历二叉树生成链表。

首先缩小问题,如果是这样的二叉树,如何中序遍历?
在这里插入图片描述

首先,根节点肯定是不能动,由于是以右节点为单链表的连接点,所以,2应该在根节点的右边,3应该在根节点的左边。

所以,我们的操作是,左右节点互换,并且把原本的右节点连接在原本左节点末尾的右边。

知道如何解决小问题之后,我们就能尝试找出遍历的方式。

我们编写一个函数,使得我们输入一个节点,它会将其进行中序遍历重排并且返回末尾的节点。

有了这个函数之后,我们就能实现该效果。

还有不理解可以看下面的注释。

代码:

在这里插入图片描述

    public void flatten(TreeNode root) {
        if(root==null)
           return;
        getEnd(root);
    }
    public TreeNode getEnd(TreeNode root){
        //如果左右子节点都为空,返回该节点
        if (root.right==root.left&&root.right==null)
            return root;
        //如果右节点为空,左节点不为空,把左节点移到右节点上开始递归
        else if (root.right==null&&root.left!=null){
            root.right=root.left;
            root.left=null;
            return getEnd(root.right);
        }
        //左节点为空,右节点不为空,直接递归右子节点
        if (root.left==null&&root.right!=null){
            return getEnd(root.right);
        }
        //如果左右节点不为空
        else 
        {
            //先要左右互换位置,记录下右节点,将子节点移动到右节点的位置
            TreeNode left=root.right;
            root.right=root.left;
            root.left=null;
            
            //先对右节点递归得到右节点排序后的末尾节点
            TreeNode end=getEnd(root.right);
            
            //左节点移至末尾,然后递归左节点
            end.right=left;
            
            TreeNode end2=getEnd(end.right);
            return end2;
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值