leetcode-141.环形链表

leetcode-141. 环形链表

给定一个链表,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

如果链表中存在环,则返回 true 。 否则,返回 false 。

示例 1:

img

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:

img

输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:

img

输入:head = [1], pos = -1
输出:false
解释:链表中没有环。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/linked-list-cycle
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

这是一道链表相关的题:

首先我第一眼看到这题,想到的思路是:一个个遍历,然后判断是否出现过重复的节点,如果出现过那么肯定存在环,不然就不存在

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class CircleLinkedList {
public static void main(String[] args) {

}
}

class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
next = null;
}
}

/**
* 遍历所有节点,每遍历一次就判断一次是否添加过
*/
class Solution {
public boolean hasCycle(ListNode head) {
Set<ListNode> set = new HashSet<>();
while (head!=null){
//保存在set集合中,并判断是否在集合中出现过
if(!set.add(head)){
return true;
}
//后移
head = head.next;
}
return false;
}
}

用时比较长,是一种常规解法,后来学习到可以使用 快慢指针来解决这题,效率很高,具体思路:

定义2个指针,一个步长为1 ,一个步长为2,让他们跑,如果有环,他们肯定会相遇,没有环就不会相遇

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//快慢指针
/*
* 我们定义两个指针,一快一满。慢指针每次只移动一步,而快指针每次移动两步。初始时,慢指针在位置 head,
* 而快指针在位置 head.next。这样一来,如果在移动的过程中,快指针反过来追上慢指针,就说明该链表为环形链表。
* 否则快指针将到达链表尾部,该链表不为环形链表。
* */
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;
}
}
-------------本文结束感谢您的阅读-------------