leetcode:linked_list_cycle_II

本文介绍了一种高效的方法来查找链表中环的起始节点,利用快慢指针技术,在不使用额外空间的情况下确定环的存在及起始位置。

一、     题目

        给定一个链表,如果链表中有环则返回环的开始节点,否则返回NULL。要求不用额外的空间完成。

二、     分析

       在I中,我们判断环的存在,即用slow和fast两个指针,设定步长fast=2;slow=1;如果两个指针可以相遇则环存在,此时如果二者相遇我们只需将slow=head;同时设置两者步长都为1,则两者再次相遇的节点即为环的开始节点。

推导过程:(图烂勿吐)

                

          当两者第一次相遇时,

          slow走过S1=x + y;

          fast走过S2=x + y + z + y,

         又知S2=2 * S1;

         所以,2 *(x+y) = x + y + z + y;

         故,x = z;

 

 

<span style="font-size:18px;">/**
 * 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 *slow = head;
	   ListNode *fast = head;
	   
	   while(fast!=NULL&&fast->next != NULL) {
	   	slow = slow->next;
	   	fast = fast->next->next;
	   	if(slow==fast) break; 
	   }  
	   if(fast==NULL||fast->next==NULL) {
	   	return NULL;
	   }
	   slow=head;
	   while(slow!=fast) {
	   	slow = slow->next;
	   	fast = fast->next;
	   }
	   return fast;
    }
};</span>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值