链表OJ题目详解(9)---判断链表是否带环

题目描述

题目分析:

之前我们遇到的都是很纯粹的单链表题目,今天这道题涉及到了链表带环问题,链表带环问题也很容易理解,就是尾节点的next并不等于空指针,而是指向了该链表当中的某一个节点,就形成了闭环,而链表带环导致最大的问题就是无法直接遍历整个链表(不知道结束标志)

思路:定义快慢指针,快指针每次走两步,满指针每次走一步,若快指针和慢指针相遇了,则带环,若快指针已经走到了空或者尾还没有和慢指针相遇,说明不带环

这个思路应该不难理解,因为不带环的话,就是一个纯粹的单链表,快慢指针同时走,快指针走的快,必然先走完链表,慢指针不可能追赶上

 思考点1:为什么带环时,快指针走两步,慢指针走一步,就一定能相遇?

假设慢指针入环时和慢指针相距L(下面是一个链表的抽象图)

 快指针每次走两步,慢指针每次走一步,因此他们之间的距离每次缩小1步,所以距离变化就是

L , L-1, L-2, ············2, 1, 0 ,因此距离一定会经过减为0的过程,因此一定能相遇

思考点2.若慢指针每次走一步,而快指针每次走N(N>2)步,那么快慢指针也一定能够相遇吗?

假设快指针每次走3步,慢指针每次走1步,会是什么情况呢?

快指针走3步,慢指针走1步,因此差距每次缩小2步,那么快慢指针距离变化过程为 L-2,L-4, L-6·······,此时要分L是奇数还是偶数:

若L为偶数:L-2, L-4, L-6·····  4, 2, 0,会经过为相距为0的时刻,也就是可以相遇

若L为奇数:L-2, L-4, L-6·····  5, 3, 1, -1,会跳过相距为0的时刻,此轮无法相遇,进入下一轮追击。开始相距C-1, 若C-1为偶数,则该轮可以相遇,若C-1为奇数,则还会跳过距离为0的时刻,永远无法相遇

这就是为什么我们要让快指针每次走两步,慢指针每次走一步的原因

完整代码

bool hasCycle(struct ListNode *head) {
    struct ListNode* fast = head;
    struct ListNode* slow = head;
    while(fast && fast->next)
    {
        fast = fast->next->next;
        slow = slow->next;
        if(fast == slow)
        return true;
    }
    return false;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值