Linked List Cycle I

Given a linked list, determine if it has a cycle in it.

Follow up:
Can you solve it without using extra space?

该问题是经典面试问题,其标准解法是用两个指针,一快一慢,如果在快的指针能够追上慢的指针,则有环,否则无环。为了熟悉一下Python,用Python又写了一遍。

/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool hasCycle(ListNode *head) {
if(head==NULL||head->next==NULL)
return false;
ListNode *flag1=head;
ListNode *flag2=head;
while()
{
if(flag1->next==NULL)
return false;
else
flag1=flag1->next;
if(flag2->next==NULL)
return false;
else
flag2=flag2->next;
if(flag2->next==NULL)
return false;
else
flag2=flag2->next;
if(flag1==flag2)
return true; }
}
};

Python版本:

# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None class Solution:
# @param head, a ListNode
# @return a boolean
def hasCycle(self, head):
if head==None or head.next==None:
return False
flag1=head
flag2=head
while True:
flag1=flag1.next
if flag1.next==None:
return False
flag2=flag2.next
if flag2.next==None:
return False
flag2=flag2.next
if flag2.next==None:
return False
if flag1==flag2:
return True

 Linked List Cycle II

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

Note: Do not modify the linked list.

Follow up:
Can you solve it without using extra space?

感觉又是一道数学题,没想了,直接看的人家是怎么做的。

转自:http://www.cnblogs.com/x1957/p/3406448.html

比I麻烦点的就是找到循环开始点TAT

I只是判断是否循环。要求不使用额外空间(不然hash就可以了

按I的思路,我们又慢指针S和快指针F。。。F走两步,S走一步。。。若有环,必定相遇。

画个图(很丑勿喷

假设在红色凸起的地方相遇了。

F走的路程应该是S的两倍

S = x + y

F = x + y + z + y = x + 2y + z

2*S = F

2x+2y = x + 2y + z

得到x = z

也就是从head到环开始的路程 = 从相遇到环开始的路程

那么。。。只要S和F相遇了,我们拿一个从头开始走,一个从相遇的地方开始走

两个都走一步,那么再次相遇必定是环的开始节点!

/**
* 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) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
if(head == NULL) return NULL;
ListNode* S = head;
ListNode* F = head; while(F != NULL){
if(F) F = F -> next;
if(F) F = F -> next;
if(S) S = S -> next;
if(F != NULL && F == S){
S = head;
while(S != F){
S = S -> next;
F = F -> next;
}
return S;
}
}
return NULL;
}
};

关于此题,网上看到一个更好的解释,解释如下:

转自:http://blog.csdn.net/sysucph/article/details/15378043

对于判断链表是否有环,方法很简单,用两个指针,一开始都指向头结点,一个是快指针,一次走两步,一个是慢指针,一次只走一步,当两个指针重合时表示存在环了。

证明:假设链表有环,环的长度为N,慢指针在起始位置,快指针在位置k(位置从0开始计数),那么快指针只要比慢指针多走经过N-k步,就可以追上慢指针了(因为之前已经多走了k步,在多走N-K步则一共多走了一圈,刚好相遇)。。。,因为每一次快指针都比慢指针多走一步,所以一定可以在有限的步数追上慢指针。

现在的问题是如何求出环的起始位置,我们先给出结论:当快指针和慢指针重合的时候,把一个指针重新指向头指针,两个指针现在速度一样,一次走一步,那么当两个指针值相同时,所在的指针就是我们要找的起始位置。

证明内容来自一个国外的网站:http://umairsaeed.com/2011/06/23/finding-the-start-of-a-loop-in-a-circular-linked-list/

要证明上面这个结论,我们先证明一个结论,假设慢指针Slow停在环的起始位置时,快指针Fast停在第k个位置,那么两个指针相遇时会停在从起始位置倒数第k个位置,也就是n-k这个位置

从Slow停在环的起始位置,假设最终停在n-x相遇。

因为Fast只要再比Slow多走n-k步,就可以追上Slow,而每一次操作Fast都比Slow多走一步,因为只需要再走n-k步就可以追上Slow,此时Slow停在n-k这个位置。

这意味着,如果Slow从环的起始位置,Fast从环的第k个位置开始,最终两个指针会在n-k这个位置相遇(n为环的长度)

假设一开始Fast和Slow从开始位置开始遍历这个链表。

令m = 3,表示经过三步,Slow结点到达环的起始位置,此时Fast在环的第m个位置,因为Fast比Slow多走了m步

根据刚才的结论,当Slow停在起始位置,Fast停在m位置,两个链表最后会在n-m位置相遇

此时把Slow移到头结点位置,两个结点都是要经过m步,才刚刚好到达环的起始位置。

这里好起来好像m小于环的长度l,才成立。其实是一样的。

假设m = t*l+k

这就是说,环最终停在n-k这个位置了。还需要k步就可以到达环的起始结点。而把Slow结点重新设置为头结点,则需要t*l+k步才第一次到达环的起始结点,

但是注意了,多走了k*l步,Fast结点还是会停在环的起始位置的。

得证!!!

和室友大神lyc交流,大神的想了一会,秒了= =!

大神的解释是这样的:假设环的长度为l,从开始到两个指针第一次相遇总共走了m步,那么Fast指针走了2*m步,Slow指针走了m步,Fast比 Slow多走了m步,Fast比Slow多走了x圈,那么有x*l==m,l是m的一个因子,再走m步,两个指针每次走一步,Fast移到开头位 置,Slow走了m步停在第一次相遇位置,Fast因为也是每次走一步,所以也会停在相遇位置,而且可以看出来,一旦Fast进入环,Fast和Slow 结点就保持相对静止了。。。碉堡了。。春哥

Linked List Cycle I&&II——快慢指针(II还没有完全理解)的更多相关文章

  1. [LeetCode题解]142. 环形链表 II | 快慢指针

    解题思路 本题是在141. 环形链表基础上的拓展,如果存在环,要找出环的入口. 如何判断是否存在环,我们知道通过快慢指针,如果相遇就表示有环.那么如何找到入口呢? 如下图所示的链表: 当 fast 与 ...

  2. 【算法分析】如何理解快慢指针?判断linked list中是否有环、找到环的起始节点位置。以Leetcode 141. Linked List Cycle, 142. Linked List Cycle II 为例Python实现

    引入 快慢指针经常用于链表(linked list)中环(Cycle)相关的问题.LeetCode中对应题目分别是: 141. Linked List Cycle 判断linked list中是否有环 ...

  3. Linked List Cycle && Linked List Cycle II

    Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Note ...

  4. LeetCode: Linked List Cycle II 解题报告

    Linked List Cycle II Given a linked list, return the node where the cycle begins. If there is no cyc ...

  5. LeetCode142:Linked List Cycle II

    题目: Given a linked list, return the node where the cycle begins. If there is no cycle, return null. ...

  6. leetcode 141. Linked List Cycle 、 142. Linked List Cycle II

    判断链表有环,环的入口结点,环的长度 1.判断有环: 快慢指针,一个移动一次,一个移动两次 2.环的入口结点: 相遇的结点不一定是入口节点,所以y表示入口节点到相遇节点的距离 n是环的个数 w + n ...

  7. 【LeetCode】142. Linked List Cycle II (2 solutions)

    Linked List Cycle II Given a linked list, return the node where the cycle begins. If there is no cyc ...

  8. LeetCode141 Linked List Cycle. LeetCode142 Linked List Cycle II

    链表相关题 141. Linked List Cycle Given a linked list, determine if it has a cycle in it. Follow up:Can y ...

  9. [算法][LeetCode]Linked List Cycle & Linked List Cycle II——单链表中的环

    题目要求 Linked List Cycle Given a linked list, determine if it has a cycle in it. Follow up: Can you so ...

随机推荐

  1. ubuntu下如何控制风扇速度?

    1.安装lm-sensors  (https://apps.ubuntu.com/cat/applications/lm-sensors/)和fancontrol(https://apps.ubunt ...

  2. Java日期时间实用工具类

    Java日期时间实用工具类 1.Date (java.util.Date)    Date();        以当前时间构造一个Date对象    Date(long);        构造函数   ...

  3. Scrapy中的Callback如何传递多个参数

    在scrapy提交一个链接请求是用 Request(url,callback=func) 这种形式的,而parse只有一个response参数,如果自定义一个有多参数的parse可以考虑用下面的方法实 ...

  4. JAVA、android中常用的一些jar包的作用

    正文: 这里主要介绍的是hibernate使用到的.jar Hibernate一共包括了23个jar包,令人眼花缭乱.本文将详细讲解Hibernate每个jar包的作用,便于你在应用中根据自己的需要进 ...

  5. vijos 1464 积木游戏 DP

    描述 积木游戏 SERCOI 最近设计了一种积木游戏.每个游戏者有N块编号依次为1 ,2,…,N的长方体积木.对于每块积木,它的三条不同的边分别称为"a边"."b边&qu ...

  6. LightOJ 1375 - LCM Extreme 莫比乌斯反演或欧拉扩展

    题意:给出n [1,3*1e6] 求 并模2^64. 思路:先手写出算式 观察发现可以化成 那么关键在于如何求得i为1~n的lcm(i,n)之和.可以知道lcm(a,b)为ab/gcd(a,b) 变换 ...

  7. debussy与modelsim的联调设置

    前段时间看到网上有人在使用debussy软件对Verilog代码进行调试,而且都称赞其是多么的好用,看着很是馋人,说吧,现在用的是quartus与modelsim的联调,似乎还是可以的,但就是每次稍微 ...

  8. 模板复习【updating】

    马上就要noi了……可能滚粗已经稳了……但是还是要复习模板啊 LCT: bzoj2049 1A 7min # include <stdio.h> # include <string. ...

  9. 【NOIP】提高组2015 运输计划

    [题意]n个点的树,m条链,求将一条边的权值置为0使得最大链长最小. [算法]二分+树上差分 [题解] 最大值最小化问题,先考虑二分最大链长. 对所有链长>mid的链整体+1(树上差分). 然后 ...

  10. iOS多线程 iOS开发Demo(示例程序)源代码

    本系列所有开发文档翻译链接地址:iOS7开发-Apple苹果iPhone开发Xcode官方文档翻译PDF下载地址(2013年12月29日更新版)   iOS程序源代码下载链接:01.大任务.zip22 ...