版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/benzhaohao/article/details/85483662
141、环形链表
给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,我们使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos
是 -1
,则在该链表中没有环。
示例 1:
输入:head = [3,2,0,-4], pos = 1 输出:true 解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0 输出:true 解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1 输出: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) {
ListNode fast=head;
ListNode slow=head;
//fast和fast.next不为空
while(fast!=null&&fast.next!=null) {
fast=fast.next.next;
slow=slow.next;
if(slow==fast)
return true;
}
return false;
}
}
142、环形链表II
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
。
为了表示给定链表中的环,我们使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos
是 -1
,则在该链表中没有环。
说明:不允许修改给定的链表。
示例 1:
输入:head = [3,2,0,-4], pos = 1 输出:tail connects to node index 1 解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0 输出:tail connects to node index 0 解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1 输出:no cycle 解释:链表中没有环。
解题思路:
参考原文:https://blog.csdn.net/ds19980228/article/details/84096184
如图所示 , 当fast与slow相遇时,slow还没走完链表,而fast已经在环内循环了n圈了,假设slow在相遇前走了s步,则fast走了2s步,设环长为r,有2s=s+nr,即s=nr.由上图可知a+x=s, x+y=r,而我们的目标是找到a的位置。设上图那个拱起的曲线的长度为y,有a+x=s=nr=(n-1)r+r=(n-1)r+y+x ,则a=(n-1)r+y . 这个公式告诉我们,在链表头和相遇点分别定义一个指针,每次各走一步,这两个指针必定相遇,且相遇的第一个点为环入口点 。
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode detectCycle(ListNode head) {
//定义快指针,慢指针,头指针
ListNode fast,slow,node;
fast=slow=node=head;
//第一步,判断链表是否有环
while(fast!=null&&fast.next!=null) {
fast=fast.next.next;
slow=slow.next;
//第二步,如果链表有环,node为环入口点
if(fast==slow) {
while(fast!=node) {
fast=fast.next;
node=node.next;
}
return node;
}
}
return null;
}
}