题目 : 给定一个链表,判断链表中是否有环。
作者解法:
/**
* 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 == NULL&&head->next == NULL)return -1;
ListNode *p = head;
ListNode *q = NULL;
for (p; p != NULL; p = p->next)
{
q = p->next;
for (q; q != NULL; q = q->next)
{
if (q == p)return false;
}
}
return true;
}
};
时间效率过低,并不能通过测试,但理解简单
本文介绍答案的两种解法
JAVA版
哈希表算法
public boolean hasCycle(ListNode head) {
Set<ListNode> nodesSeen = new HashSet<>();
while (head != null) {
if (nodesSeen.contains(head)) {
return true;
} else {
nodesSeen.add(head);
}
head = head.next;
}
return false;
}
本方法利用了哈希表的高效性
将未识别过的添加至表中,若又遇到识别过,则返回正确,否则到达链表尾部返回错误
双指针解法:
public boolean hasCycle(ListNode head) {
if (head == null || head.next == null) {
return false;
}
ListNode slow = head;
ListNode fast = head.next;
while (slow != fast) {
if (fast == null || fast.next == null) {
return false;
}
slow = slow.next;
fast = fast.next.next;
}
return true;
}
将实际问题转化为跑圈问题,当速度快,一次跳两步的再次遇到速度慢的,则会返回ture,
到达末尾则返回ture,时间复杂度o(n);