单链表荷兰国旗问题思路

题目要求:
给定一个单链表,在给你一个数,现在,请你把单链表中大于这个数的放在右边,小于这个数的放在左边,等于这个数的放在中间。

如果不加特殊限制,这种题目一般出现在笔试题中,用最快方法解决:
经典荷兰国旗问题,是在数组中实现,而此题是在单链表中实现,如果是笔试题,此题最快的解决办法,就是创建一个数组,然后将单链表中的数直接复制到数组中,然后直接用经典荷兰国旗问题解决就好了。经典荷兰国旗问题,可以参考我之前的博客:https://blog.csdn.net/weixin_43923436/article/details/112172539

然而,此题如果出现在面试题中,增加了限制条件,要求空间复杂度O(1),并且要求稳定性。如何解答?
其实,这种问法一般出现在面试中,面试官问你这种问题,其实就是想考察你以下几点:
1.你知道什么是稳定性,先解释下稳定性的概念。
2.你知道荷兰国旗问题是不具备稳定性的,以此推断出,快排是不稳定的。
3.你知道链表问题通常可以节省额外空间实现。
4.你的解题思路达标。
其实面试的时候,只有一个根本目的,那就是,让面试官因为你想问题的思路和方式喜欢你,因此,一定要思路清晰,逻辑紧密。

思路:
首先,链表问题就是链接和断链操作,在这些操作过程中,因为链接断链操作对相邻链表很容易实现,因此,就也就是链表问题通常可以节省空间的原因,不需要辅助空间,只需要保存额外指针就行。
其次,再分析链表问题的特殊性,可以发现,链表的话,通常要求的是一条路能够走通就行,也就是说,通常不要求一个节点到底有几个指针指向他。
看懂了以上两点,现在来分析这道题的思路,首先,因为链表可以只保存指针就行,因此,创建less,equals,more,三个数据结构,这三个数据结构中,其实只包含两个指针,一个指向前面,一个指向后面。比如,less里面的两个指针,头指针指向小于当前数num的第一个节点,后面的指针指向最后一个比num小的节点。因此,其实就是相当于自己再创建一套指针,然后,在原来单链表的基础上,创建自己的指针系统,节点还是那几个节点,只不过多了一套指针路径而已,因此,并不扩充额外空间。 这个思路,就相当于,城市还是那几个城市,只不过多了几条路而已。
具体做法:
1.创建less,equals,more,三个数据结构
2.便利一遍原来的链表,找到第一个小于num的节点,让less中的头节点指向他;找到第一个等于num的节点,让equals中的头节点指向他;找到第一个大于num的节点,让more中的头节点指向他。
3.再便利一遍原来的链表,这次,每找到一个比num小的节点,就看看是否是less中的头节点,如果不是,就链接在less中,让less中的指向后面的指针指向最后连上的节点,相当于,从头往后找小于num的,依次链接在less中,因此,是稳定的。equals和more同理。
4.此时,less中是所有比num小的,依次链接起来了,equals和more同理。因此,只需要把less的指向后面的指针指向equals的头指针,然后equeals的最后的指针指向more的头指针,串起来就行了。

总结一下:
这个过程,就类似于,三个链子,每来一个新的,就判断应该连到哪个上面,在这个过程中,每一个新节点,既仍然被原来的链子连着,又被新链子接上了,相当于同时被两个链子连着,但是并不影响。直到原来的上一个节点,重新链接上新的,才会打断。在这个过程中,节点还是那些节点,并没有申请额外空间,多的只不过是几条链子而已,因此,空间复杂度O(1)。这就是链表的特殊之处。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值