leetcode-Linked List Cycle I & II
2014-09-08 12:36
441 查看
继续刷题,虽然是水水得有空有兴趣了才上来刷两道,但还是希望坚持刷下去。
这次的两道题是Linked List Cycle,就是判断一个单向链表有没有换,第二道要求有环的话,输出环首的节点,当然题目对使用的空间有要求(原句是:Can you solve it without using extra space?
好想说:- - no)。
还在看题目就被旁边的众大神们告知,这是经典题目啦,快慢指针轻松解出来啊,还可以证明的啦,blablabla.......于是又乖乖得去看经典解法了。哎 - - 没网络怎么办啊。
解法大致为:用两个指针,一个一次跑1步,一个一次跑2步,如果快指针能追上慢指针,就说明有环,如果快指针先到了链表尾部说明没有环,but 为什么一个一次2步一个一次1步有环就一定能追上呢?解释如下:因为快指针每次2步,慢指针每次1步,那如果有环的情况下,2者之间的距离没经过一次循环就减少1步的距离,所以如果有环就一定会相遇。但要找到环的开头的话,就需要另外的方法了,具体做法是:当快慢指针相遇时,让快指针从链表头和慢指针一起重新开始遍历,两者都是每次一步,当2者再次相遇时,所指向的节点就是环的头节点了。证明如下:第一次相遇时,慢指针走了n=p+c(p为入环前的长度,c为环起点到两个指针相遇点的距离);快指针走了2n=p+c=kl(快指针的速度是慢指针的两倍,走的路程必然是2n,快指针重复了慢指针的p+c路程,又多走了整数个环的长度,k为整数,l为环的长度),所以可以得到n=p+c=kl,即kl-c=p,即此时慢指针从链表头重新开始按速度1来走,走p步,慢指针一定也到环的开头的快指针相遇,这样就能找到环的开头了,bingo。
原谅我文字水平太渣,还是上代码吧:
检测是否有环:
这次的两道题是Linked List Cycle,就是判断一个单向链表有没有换,第二道要求有环的话,输出环首的节点,当然题目对使用的空间有要求(原句是:Can you solve it without using extra space?
好想说:- - no)。
还在看题目就被旁边的众大神们告知,这是经典题目啦,快慢指针轻松解出来啊,还可以证明的啦,blablabla.......于是又乖乖得去看经典解法了。哎 - - 没网络怎么办啊。
解法大致为:用两个指针,一个一次跑1步,一个一次跑2步,如果快指针能追上慢指针,就说明有环,如果快指针先到了链表尾部说明没有环,but 为什么一个一次2步一个一次1步有环就一定能追上呢?解释如下:因为快指针每次2步,慢指针每次1步,那如果有环的情况下,2者之间的距离没经过一次循环就减少1步的距离,所以如果有环就一定会相遇。但要找到环的开头的话,就需要另外的方法了,具体做法是:当快慢指针相遇时,让快指针从链表头和慢指针一起重新开始遍历,两者都是每次一步,当2者再次相遇时,所指向的节点就是环的头节点了。证明如下:第一次相遇时,慢指针走了n=p+c(p为入环前的长度,c为环起点到两个指针相遇点的距离);快指针走了2n=p+c=kl(快指针的速度是慢指针的两倍,走的路程必然是2n,快指针重复了慢指针的p+c路程,又多走了整数个环的长度,k为整数,l为环的长度),所以可以得到n=p+c=kl,即kl-c=p,即此时慢指针从链表头重新开始按速度1来走,走p步,慢指针一定也到环的开头的快指针相遇,这样就能找到环的开头了,bingo。
原谅我文字水平太渣,还是上代码吧:
检测是否有环:
<span style="font-size:10px;">public class Solution { public boolean hasCycle(ListNode head) { if(head == null || head.next == null){ return false; } ListNode p1 = head.next; ListNode p2 = head.next.next; while(p1 != p2 && p2 != null && p2.next != null){ p1 = p1.next; p2 = p2.next.next; } if(p2 == null || p2.next == null){ return false; }else{ return true; } } }</span>检测环并找到环的入口:
<span style="font-size:10px;">public class Solution { public ListNode detectCycle(ListNode head) { if(head == null || head.next == null){ return null; } ListNode p1 = head.next; ListNode p2 = head.next.next; while(p1 != p2 && p2 != null && p2.next != null){ p1 = p1.next; p2 = p2.next.next; } if(p2 == null || p2.next == null){ return null; }else{ p2 = head; while(p2 != p1){ p1 = p1.next; p2 = p2.next; } return p2; } } }</span>
相关文章推荐
- LeetCode Linked List Cycle && Linked List CycleII
- 【leetcode】Linked List Cycle I & II
- LeetCode之“链表”:Linked List Cycle && Linked List Cycle II
- LeetCode解题报告:Linked List Cycle && Linked List Cycle II
- [LeetCode]Linked List Cycle & Linked List Cycle II——单链表中的环
- [Leetcode 141 & 142, medium] Linked List Cycle (I and II)
- LeetCode: Linked List Cycle I & II
- [Leetcode] #141#142 Linked List Cycle I & II
- Leetcode 142: Linked List Cycle II & Leetcode 287: Find the Duplicate Number
- leetcode--Linked List Cycle &Linked List Cycle II
- leetcode day5 -- Reorder List && Linked List Cycle II
- LeetCode Linked List Cycle & Linked List Cycle II
- LeetCode: Linked List Cycle I && II
- leetcode 141.Linked List Cycle && 142 .Linked List Cycle ii
- [leetcode] 141& 142 Linked List Cycle I& II
- [算法][LeetCode]Linked List Cycle & Linked List Cycle II——单链表中的环
- 【LeetCode】Linked List Cycle I&II
- Leetcode | Linked List Cycle I && II
- Leetcode 141/142 (链表题) Linked List Cycle && Linked List Cycle II
- LeetCode:Linked List Cycle && Linked List Cycle II