题目要求:判断一个链表(linked list)中是否含有环路
方法一:floyd算法。形象称为龟兔赛跑算法。维持两个指针rabbit和turtle,turtle一次前进一步,rabbit一次前进两步,如果两个指针能够相遇,则说明含有环路
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public boolean hasCycle(ListNode head) {
ListNode rabbit = head;
ListNode turtle = head;
while(true){
if(rabbit == null)
return false;
rabbit = rabbit.next;
if(rabbit == null)
return false;
rabbit = rabbit.next;
turtle = turtle.next;
if(rabbit == turtle)
return true;
}
}
}
方法二:Brent算法。是基于floyd算法思想的改进。仍然维持两个指针,turtle原地不动,rabbit一次前进一步,同时维护两个变量,step_taken表示rabbit已经走的步数,rabbit每走一步其值加一。step_limit表示rabbit所走步数的上限值,当step_taken值达到step_limit上限时,直接将turtle移到rabbit所在的位置,然后重复执行,如果turtle和rabbit相遇,表示有环。
public class Solution {
public boolean hasCycle(ListNode head) {
int step_taken = 0;
int step_limit = 2;
ListNode rabbit = head;
ListNode turtle = head;
while(true){
if(rabbit == null)
return false;
rabbit = rabbit.next;
step_taken++;
if(rabbit == turtle)
return true;
if(step_taken == step_limit){
turtle = rabbit;
step_limit *= 2;
step_taken = 0;
}
}
}
}