版权声明:我的GitHub:https://github.com/617076674。真诚求星! https://blog.csdn.net/qq_41231926/article/details/86090509
我的LeetCode代码仓:https://github.com/617076674/LeetCode
原题链接:https://leetcode-cn.com/problems/linked-list-cycle/description/
题目描述:
知识点:哈希表、双指针、链表
思路一:用一个hashSet来存储已经遍历过的节点
一旦发现某个节点的next节点已经被遍历过,则说明存在环。
时间复杂度和空间复杂度均是O(n),其中n为链表中的节点个数。
JAVA代码:
public class Solution1 {
public boolean hasCycle(ListNode head) {
HashSet<ListNode> hashSet = new HashSet<>();
ListNode dummyHead = new ListNode(-1);
dummyHead.next = head;
ListNode cur = dummyHead;
while(null != cur.next){
if(hashSet.contains(cur.next)){
return true;
}
cur = cur.next;
hashSet.add(cur);
}
return false;
}
}
LeetCode解题报告:
思路二:用快慢双指针遍历链表
快指针一次移动两步,慢指针依次移动一步。将快慢双指针想象成两个运动员在赛跑,如果链表有环,那么终有一个时刻快慢双指针会重合。一旦某个节点的next节点出现null,说明不是环形链表。
时间复杂度的分析分为两种情况:
(1)链表中不存在环,显然其时间复杂度是O(n),其中n是链表中的节点个数。
(2)链表中不存在环,将慢指针的移动过程划分为两个阶段:非环部分与环形部分:
a:慢指针在走完非环部分阶段后将进入环形部分:此时,快指针已经进入环中,且已经迭代了p次,其中p为非环部分的长度。
b:两个指针都在环形区域中:考虑两个在环形赛道上的运动员——快跑者每次移动两步而慢跑者每次只移动一步。其速度的差值为1,因此需要经过q次循环后快跑者可以追上慢跑者,其中q为快跑者与慢跑者之间的距离。这个距离几乎就是环形部分的长度。
因此,总的时间复杂度依然是O(p + q) = O(n)。空间复杂度是O(1)。
JAVA代码:
public class Solution {
public boolean hasCycle(ListNode head) {
ListNode dummyHead = new ListNode(-1);
dummyHead.next = head;
ListNode cur1 = dummyHead;
ListNode cur2 = dummyHead;
while(true){
if(null == cur2.next || null == cur2.next.next){
return false;
}
cur1 = cur1.next;
cur2 = cur2.next.next;
if(cur1 == cur2){
return true;
}
}
}
}
LeetCode解题报告: