📝个人主页:五敷有你
🔥系列专栏:算法分析与设计
⛺️稳中求进,晒太阳
题目
给你一个链表的头节点 head
,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next
指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos
不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true
。 否则,返回 false
。
示例
示例 1:
输入:head = [3,2,0,-4], pos = 1 输出:true 解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0 输出:true 解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1 输出:false 解释:链表中没有环。
思路
快慢指针
你可以使用快慢指针的方法来判断链表是否有环。快指针每次移动两步,慢指针每次移动一步,如果存在环,快指针最终会追上慢指针。
先检查头节点和头节点的下一个节点是否为null,如果是,则返回false。然后使用快慢指针方法,初始化快指针为头节点的下一个节点,慢指针为头节点,然后在一个while循环中,快慢指针分别向前移动。如果快指针或快指针的下一个节点为null,说明链表无环,返回false;如果快慢指针相遇,说明链表有环,返回true。
Set集合
定义了一个HashSet来存储已经遍历过的节点。然后,我们从头节点开始遍历链表,对于每个节点,我们检查它是否已经在HashSet中存在,如果存在则说明链表有环,返回true;否则,将节点加入HashSet中。如果遍历完整个链表都没有发现环,则返回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) {HashSet<ListNode> set = new HashSet<>();ListNode current = head;while (current != null) {if (set.contains(current)) {return true; // 发现环}set.add(current);current = current.next;}return false; // 遍历完整个链表都没发现环}
}
Set集合
/*** 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) {HashSet<ListNode> set = new HashSet<>();ListNode current = head;while (current != null) {if (set.contains(current)) {return true; // 发现环}set.add(current);current = current.next;}return false; // 遍历完整个链表都没发现环}
}
运行结果
快慢指针
- 在这种方法中,我们使用两个指针,一个慢指针和一个快指针。慢指针每次移动一步,快指针每次移动两步。
- 在最坏情况下,如果链表中没有环,那么快指针将会先到达链表的末尾,此时时间复杂度为O(n),其中n是链表中节点的个数。
- 如果链表中有环,快慢指针都会进入环中,因为快指针每次比慢指针多走一步,所以它们最终会相遇,时间复杂度也是O(n),其中n是环的长度。这是因为在环中,快指针每次能够靠近慢指针一步,因此需要经过环的长度次数才能相遇。
因此,使用快慢指针的方法的时间复杂度是O(n)。
Set集合
- 在这种方法中,我们使用一个HashSet来存储已经访问过的节点。
- 在最坏情况下,如果链表中没有环,那么我们需要遍历整个链表并将每个节点加入HashSet中,时间复杂度为O(n),其中n是链表中节点的个数。
- 如果链表中有环,我们同样需要遍历整个链表,但在某个时刻我们会发现HashSet中已经存在了某个节点,这时就说明链表有环。因此时间复杂度依然是O(n),其中n是链表中节点的个数。
因此,使用HashSet的方法的时间复杂度也是O(n)。