141. Linked List Cycle
Given a linked list, determine if it has a cycle in it.
Follow up:
Can you solve it without using extra space?
/**
* 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) {
ListNode* cur = head;
bool flag = false;
while (head && cur) {
head = head->next;
cur = cur->next;
if (!cur) break;
cur = cur->next;
if (head == cur) {
flag = true;
break;
}
}
if (flag) return true;
return false;
}
};
142. 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?
这题值得好好写写题解。
首先,我们判断是否成环,采用上一题的思路,设置两个指针,slow和fast,当相遇时成环。此时假设链表环上节点数为r,相遇位置为k,则slow走了k步fast走了2k步。2k - k = nr,可得k = nr。然后,设链表开始结点与环开始结点的距离为s,设环开始结点到k之间的距离为m,则存在s = k - m,即 s = nr - m = (n - 1)r + (r - m),取n = 1,可得s = r - m。
所以,我们再设置一个指针ans指向链表的开头,与slow指针同时前进,每次一步。当slow指针走完那圈剩下的结点时,ans指针恰好走了s步,与slow指针相遇,此时的位置便是环开始的结点的位置。
/**
* 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) {
if (!head) return NULL;
ListNode* slow = head;
ListNode* fast = head;
ListNode* ans = head;
while (fast->next && fast->next->next) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) {
while (slow != ans) {
slow = slow->next;
ans = ans->next;
}
return ans;
}
}
return NULL;
}
};