Leecode刷题——链表——环形链表(快慢指针)

本次总结的是链表中的环形链表,环形链表是链表的重难点之一,环形的结构有许多巧妙的地方,看看下面这道题

环形链表II(相关题号:142)

例142题目:

1.快慢指针

快慢指针是双指针法的一种经典用法,设立两个指针fast和slow,在遍历的过程中这两个指针的步幅不一样(例如本题中fast步幅为2,slow为1),这样的做法通常可以针对一些环形链表相遇问题(因为fast比slow快,有环的话是会再追上slow的)针对本题,fast步幅为2,slow为1这样再进入换之后fast一定会在某时和slow相遇,然后构造数学思维解答题目

2.判断环形的入口(结合数学思维)

利用1中所说的快慢指针当两个指针相遇的时候,这时候我们抽象分析链表各部分的情况,如下图:

可以看到slow走了x+y,fast走了x + y + n (y + z)【n为fast在环内走了几圈】,此时因为fast的速度是slow的两倍所以可以得到公式:2*(x+y)=x + y + n (y + z),可以推得x=(n-1)(y+z)+z,于是便可以得知,某个指针从头结点走x步相当于从相遇节点走(n-1)(y+z)+z步,而(n-1)(y+z)相当于走了n-1圈回到了原来的位置,某个指针从头结点走x步相当于从相遇节点走z步,而从相遇节点走z步恰好走到入环口节点!所以新设立指针index1和index2分别从头结点和相遇节点移动(步幅都为1),直到他们相遇(相等)(注意搞清楚不是fast和slow的相遇节点)既可以得到环的入口结点,概念图如下:

 3.代码(Java运行出现问题所以用的c++)

/**
 * 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 != NULL && fast->next != NULL) {
            slow = slow->next;
            fast = fast->next->next;
            // 快慢指针相遇,此时从head 和 相遇点,同时查找直至相遇
            if (slow == fast) {
                ListNode* index1 = fast;
                ListNode* index2 = head;
                while (index1 != index2) {
                    index1 = index1->next;
                    index2 = index2->next;
                }
                return index2; // 返回环的入口
            }
        }
        return NULL;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值