个人主页:五敷有你
系列专栏:算法分析与设计
⛺️稳中求进,晒太阳
给你一个链表的头节点 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。
定义了一个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 set = new HashSet<>();
ListNode current = head;
while (current != null) {
if (set.contains(current)) {
return true; // 发现环
}
set.add(current);
current = current.next;
}
return 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 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)。
因此,使用HashSet的方法的时间复杂度也是O(n)。