JAVA解法
方法一:快慢指针
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
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;
}
}
题解分析
利用快慢指针来判断链表是否含环的原理是:若链表存在环,那么快的指针一定在某时刻遇上慢指针。
题目是让快指针走两步,慢指针走一步,若不存在环的话,两个指针最后都为空,若存在环,则都绕圈,由于步频不一样,最终会相遇,因此当相遇时结束循环返回 true,否则遇到 null 返回 false。
方法二:哈希值
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public boolean hasCycle(ListNode head) {
// 利用 set 的不可重复的特性
Set<ListNode> seen = new HashSet<ListNode>();
// 将所有的节点存到 set 里边,若存不进去则存在环
while (head != null) {
if (!seen.add(head)) {
return true;
}
head = head.next;
}
return false;
}
}
题解分析
利用 set 的不可重复的特性,循环将所有节点加入 HashSet,若加入不成功则存在环。
leetcode原题: 141. 环形链表
点评
leetcode 的提交记录中,方法一执行时间为 0ms 而方法二要 4ms,两者在内存的使用上基本相等,可见双指针效率比较高。
评论区