Given a linked list, determine if it has a cycle in it.
Follow up:
Can you solve it without using extra space?
問題需求:
問題分析:判斷出單鏈表是否帶有循環。
對於一個普通的單鏈表(雙向鏈表以及循環鏈表不算在內),鏈表最後一個元素指針==NULL,一個帶有循環的單鏈表,就是鏈表最後一個結點的指針域,指向鏈表裏的其中一個結點(1,可以指向頭個結點,此時最後一個結點的指針域的值==頭指針值,2,或者只想最後一個結點本身;3,或者指向其他任意一個結點)。解題關鍵是使用一快一慢兩個的指針,就像操場上面跑步的人,速度不同總有遇上的時候的,遇上那時,兩個指針的值相等。
解題思路
採用快慢指針法來實現,每當一個指針跳動兩次另外一個指針跳動一次,如果鏈表示帶有循環的,這兩指針總會遇上。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
bool hasCycle(struct ListNode *head) {
struct ListNode* p = NULL;//這個就是快指針了
struct ListNode* q = NULL;這個就是慢指針了
int i = 0;
//如果是一個空鏈表
//當然就不帶循環了
if(head==NULL){
return 0;
}
//如果鏈表只有一個元素
//看他是否指向自己,如果指向自己就是帶循環的
if(head->next == head){
return 1;
}
//以下針對鏈表元素超過兩個進行判斷
p = head->next;
q = head;
while(p!=NULL){
p = p->next;
//p每移動一次都要判斷是否是空,如果是空那就是個普通鏈表
if(p == NULL){
break;
}
//兩個指針一旦相等就是帶有循環的了
if(p == q){
return 1;
}
//計數保證快的指針每週兩次慢的指針才走一次
i = (i+1)%2;
if(i==0)
q = q->next;
}
//如果while循環能跳出說明這個鏈表裏面沒有循環
return 0;
}