解法1:我的解法就是用那个大众化的两个指针,一快一慢,看最后能不能相遇。
#include <iostream>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
bool hasCycle(ListNode *head) {
if (!head) return false;
ListNode *p1=head, *p2=head->next;
while(p1!=p2) {
if (!p2 || !p2->next) return false;
p1=p1->next;
p2=p2->next->next;
}
return true;
}
int main()
{
ListNode a=ListNode(1);
ListNode b=ListNode(2);
ListNode c=ListNode(3);
ListNode d=ListNode(4);
ListNode e=ListNode(5);
a.next=&b;
b.next=&c;
c.next=&d;
d.next=&e;
e.next=&a;
cout<< hasCycle(&a);
return 0;
}
下面这个写法也可以:
class Solution {
public:
/**
* @param head: The first node of linked list.
* @return: True if it has a cycle, or false
*/
bool hasCycle(ListNode * head) {
if (!head) return false;
if (!head->next || !head->next->next) return false;
ListNode * p1 = head, * p2 = head;
while(p2->next && p2->next->next) {
p1 = p1->next;
p2 = p2->next->next;
if (p1 == p2) return true;
}
return false;
}
};
这个写法也可以:
class Solution {
public:
/**
* @param head: The first node of linked list.
* @return: True if it has a cycle, or false
*/
bool hasCycle(ListNode * head) {
if (!head) return false;
if (!head->next || !head->next->next) return false;
ListNode * p1 = head, * p2 = head;
while(p2 && p2->next) {
p2 = p2->next;
if (p1 == p2) return true;
p1 = p1->next;
p2 = p2->next;
}
return false;
}
};
解法2:也可以用set或map,里面的元素就是Node的地址,看有没有重复元素。
解法3: 在网上看到有个解法如下,它没有用额外空间,却是把val指向前置节点。感觉有点意思,copy在下面。
bool hasCycle(ListNode *head) {
if (head == nullptr)
{
return false;
}
while (true)
{
if (head->next == nullptr)
{
return false;
}
if (head->next->val != static_cast<int>(reinterpret_cast<uintptr_t>(head)))
{
head->next->val = static_cast<int>(reinterpret_cast<uintptr_t>(head));
head = head->next;
continue;
}
return true;
}
}