題目
給定一個鏈表,判斷鏈表中是否有環。
要求:
你能否不使用額外空間解決此題?
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
bool hasCycle(struct ListNode *head) {
//在此處編輯代碼
}
題解
思路: 用一對快慢指針同時遍歷鏈表,慢指針一次 相遇則說明有環
note:注意fast是否爲空,爲空則不能使用fast->next
bool hasCycle(struct ListNode *head) {
if (head == NULL) return false;
struct ListNode *slow = head, *fast = head->next;
while (slow != fast && fast && fast->next ) {
slow = slow->next;
fast = fast->next->next;
}
if (fast == NULL || fast->next == NULL) return false;
return true;
}
此代碼中,判斷條件fast 和fast->next位置不能互換 ,否則當fast==NULL時會出錯
拓展
返回鏈表中環的起點
示例:
n1 -> n2 -> n3 ->n4
↑ ↓
n6 <- n5
起點爲n3
思路: 當快慢指針相遇時,距離環起點的節點數一定等於環外節點數,所以相遇後,在相遇點和起點建立指針,同時開始向後遍歷,這兩個指針的相遇點即爲環起點
struct ListNode* hasCycle(struct ListNode *head) {
if (head == NULL) return false;
struct ListNode *slow = head, *fast = head->next;
while (slow != fast && fast && fast->next ) {
slow = slow->next;
fast = fast->next->next;
}
if (fast == NULL || fast->next == NULL) return NULL;
*slow = head;
while (slow != fast) {
slow = slow->next;
fast = fast->next;
}
return slow;
}