141 环形链表
一、题目
给你一个链表的头节点 head ,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true 。 否则,返回 false 。

二、题解
思路: 快慢指针(龟兔赛跑)。
- 慢指针
slow每次走 1 步,快指针fast每次走 2 步。 - 如果链表无环,
fast会先到达null(链表尾部),返回false。 - 如果链表有环,
fast终会在环内追上slow(两者相遇),返回true。
/**
* 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) {
// 【边界情况】如果链表为空,或者只有一个节点,根本构不成环,直接返回 false
if(head == null || head.next == null) {
return false;
}
// 【初始化快慢指针】
// 慢指针 slow 起点在 head,快指针 fast 起点在 head.next。
// (让 fast 先走一步,是为了能顺利进入下面的 while 循环条件判断)
ListNode slow = head, fast = head.next;
// 【核心循环】只要两个指针没相遇,就一直跑
while(slow != fast){
// 如果快指针走到了尽头(遇到 null),说明链表是有尾巴的,绝对没有环
if(fast == null || fast.next == null) {
return false;
}
// 慢指针每次走 1 步
slow = slow.next;
// 快指针每次走 2 步
fast = fast.next.next;
}
// 如果能跳出 while 循环,说明 slow 和 fast 相遇了!必定有环
return true;
}
}
时间复杂度:
空间复杂度:
评论