原题连接:Leetcode 141.Linked List Cycle
Given head, the head of a linked list, determine if the linked list has a cycle in it.
There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the next pointer. Internally, pos is used to denote the index of the node that tail’s next pointer is connected to. Note that pos is not passed as a parameter.
Return true
if there is a cycle in the linked list. Otherwise, return false
.
Example 1:
Input: head = [3,2,0,-4], pos = 1
Output: true
Explanation: There is a cycle in the linked list, where the tail connects to the 1st node (0-indexed).
Example 2:
Input: head = [1,2], pos = 0
Output: true
Explanation: There is a cycle in the linked list, where the tail connects to the 0th node.
Example 3:
Input: head = [1], pos = -1
Output: false
Explanation: There is no cycle in the linked list.
Constraints:
Follow up : Can you solve it using O(1) memory?
遍历一遍链表,将遍历到的 结点 存入链表中,如果重复就返回true
注意 : 哈希表中一定要存结点而不是结点的值。因为链表中不同结点的值可能相同,但他们不是同一个结点
/**
* 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) {
if(!head || !head->next)
return false;
unordered_set<ListNode*> st;
while(head != nullptr){
if(st.count(head))
return true;
st.insert(head);
head = head->next;
}
return false;
}
};
Floyd 判圈算法,也龟兔赛跑算法:
设置快慢两个指针,慢的一次移动一位,快的一次移动两位,如果存在环,那么快的指针一定会从后面追上慢的指针
/**
* 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) {
if (!head || !head->next) {
return false;
}
// 注意此处fast的起点
ListNode* slow = head;
ListNode* fast = head->next;
while (slow != fast) {
// 如果有指针先到NULL说明无环
if (!fast || !fast->next) {
return false;
}
// 慢指针移动一位 快指针移动两位
slow = slow->next;
fast = fast->next->next;
}
return true;
}
};