142、环形链表

思路:

判断链表是否有环

使用快慢指针,头节点出发,fast每次移动两个节点,slow就移动一个节点,如果fast和slow相遇的话,就说明链表有环。

问题1:为什么fast每次移动两个节点,slow每次移动一个节点,就一定会在环中相遇,而不是永远错开呢?

fast进入环,如果fast和slow相遇,那么一定是在环中相遇,因为每次移动两者总会产生差距。fast在一直追slow。

2.如何找到在循环中的的判断条件呢?何时跳出?

如果没有环,随着循环,那么fast肯定会先指向为空,当fast或者fast->next为空的时候,那么就跳出循环,说明没有环,返回null。

如果有环,fast就不可能为空,当slow和fast相等时,正式说明有环,此时应该寻找环形链表的第一个入口。

3.如何寻找环的入口呢?

这个有一点点难解释,过程可以看《代码随想录》66页的解释。电子版链接

简略为一个指针从头节点开始,另一个指针为fast和slow相遇节点开始,两个节点同时开始移动,每次都移动一个节点。相遇的位置就是第一个环的入口。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode* fast = head;
        ListNode* slow = head;
        while(fast != nullptr && fast->next !=nullptr){
            slow = slow ->next;
            fast = fast->next->next;
        
            if(slow == fast){
              ListNode* index1 = fast;
              ListNode* index2 = head;
              while(index1 !=index2 ){
                 index1 = index1->next;
                 index2 = index2->next;
              }
              return index2;
            }
        }
        return nullptr;
    }
};

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值