线性表的应用2——快慢指针问题

快慢指针

貌似是哪个大厂的面试题吧,让你找到一个链表的中间节点,
第一反应遍历数个数,然后跑到中间那个就行了呗。
貌似标准答案也差不多这样,但是有一个dl就不一样,他的思路是这样的:
两个指针,一个慢,一次走一格;一个快,一次走两格。
当快指针到最后,慢指针就到了中点位置了。

例一,求链表倒数第k个结点的元素

利用上面的思想,快慢指针,不过这次是有一个指针先走k’格,然后两个一起前进,当先行的指针到最后,另一个指针的位置就是倒数第k个。

例二,存储两个后缀相同的英文单词

说有两个英文单词,每一个字母都是由链表保存,那么后缀的链表就是相同的,如果能把他们合并,就可以省一部分空间,所以需要找到相同后缀的第一个字母。
方法
首先需要两个单词尾部对齐,计算两个单词的长度,让长的先走,等到对齐了之后两个指针同时后移,找到第一个相同的元素,记录下来然后往后走,直到结束,如果相同就返回,如果有不同的就清除记录,最后的记录就是后缀的起点。(同样如果没有记录就是没有相同后缀)

例三,判断两个链表是否相交

因为链表只有一个指针,所以交叉只可能是两个结点后继相同,不可能是一个结点有两个后继。
地址是每一个链表最好的“元素”,都不带重复的,所以只要对齐了之后看有没有相同的地址就行了。

至于其他的方法也有很多,这个不唯一。

例四,判断链表是否有环

这个比较有趣,如果是单纯判断的话,可以考虑跑步。
如果有环,那必然不论两个人谁快谁慢,必然相遇,但如果没有,那么快的先到NULL,也就是走完。
快慢指针,开始表演。

int judge(struct link* head)
{
    struct link* fast=head->next,*slow=head->next;
    while(fast&&fast->next)
    {
        fast=fast->next->next;
        slow=slow->next;
        if(fast==slow)//相遇,有环
            return 1;
    }//while结束
    return 0;
}

但如果还要判断环的入口,这个会比较烦,这其实是一个数学问题(就nm离谱)
现在有三个点,起始点、入口点、指针交点,设起始点和入口点的距离是x,入口和交点的距离是y,快指针走了n圈,一圈r个点。这里一定要明白一个事情,慢指针走一圈,快指针能走两圈多x,所以相遇慢指针必然还没到一圈。
此时慢指针走的距离是x+y,则2(x+y)=nr+(x+y) 则x=nr-y。
来了来了,取一个指针在起始点,另一个指针在交点,在起点的指针走了x之后到达入口点,另一个走了nr-y,算上之前的y,刚好也到达入口点。、

一个比较有趣的,emmm 数学题?

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值