Linked List Cycle II

分析转自:http://www.cnblogs.com/CSGrandeur/p/3520937.html

设置两个指针slow和fast,从head开始,slow一次一步,fast一次两步,如果fast能再次追上slow则有圈。

设slow走了n步,则fast走了2*n步,设圈长度m,圈起点到head距离为k,相遇位置距离圈起点为t,则有:

n = k + t + pm; (1)

2*n = k + t + qm;(2)

这里p和q是任意整数。(不过fast速度是slow二倍,则肯定在一圈内追上,p就是0了)

2 * (1) - (2) 得k = lm - t;(l = q - 2 * p)

 即 k 的长度是若干圈少了 t 的长度。

因此这时候,一个指针从head开始,另一个从相遇位置开始,都每次只走一步,当从head开始的指针走到圈开始位置时,两指针刚好相遇。

/*
 * Solution.cpp
 *
 *  Created on: 2014年4月9日
 *      Author: William
 */

#include <iostream>
using namespace std;

// 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* pfast = head;
		ListNode* pslow = head;
		do {	// Elegant, compared with Linked List Cycle done by me.
			if (pfast != NULL)
				pfast = pfast->next;
			if (pfast != NULL)
				pfast = pfast->next;
			if (pfast == NULL)
				return pfast;
			pslow = pslow->next;
		} while (pfast != pslow);
		pfast = head;
		while (pfast != pslow) {
			pfast = pfast->next;
			pslow = pslow->next;
		}
		return pfast;
	}
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值