学习目标:
目标:熟练运用Java所学知识
学习内容:
本文内容:使用Java实现:环形链表Ⅱ
题目描述:
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。
说明:不允许修改给定的链表。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1
输出:返回 null
解释:链表中没有环。
解题步骤:
- 第一步:排除空链表和只有一个节点的情况
//排除空链表和只有一个节点的情况
if(head==null||head.next==null){
return null;
}
- 第二步:判断链表是否带环
//通过循环判断链表是否带环
while(fast!=null&&fast.next!=null){
fast=fast.next.next;
slow=slow.next;
if(fast==slow){
//表示链表带环,结束循环
break;
}
}
- 第三步:如果链表没有环,则返回空
//判断上述while循环结束的原因,只有两个原因
//第一个原因:如果快指针走到了链表结尾,则返回null
if(fast==null||fast.next==null){
return null;
}
- 第四步:链表带环,找到链表入环的第一个结点
如果链表带环,则 快慢指针相遇的结点 和 链表头结点 距离链表入环的第一个结点是相同的所以只需要同步遍历,直到第一次相遇既为链表入环的第一个结点
//第二个原因:链表带环
//如果链表带环,则 快慢指针相遇的结点 和 链表头结点 距离链表入环的第一个结点是相同的
//所以只需要同步遍历,直到第一次相遇既为链表入环的第一个结点
while(cur!=fast){
cur=cur.next;
fast=fast.next;
}
return fast;
实现代码:
public static ListNode detectCycle(ListNode head) {
//排除空链表和只有一个节点的情况
if(head==null||head.next==null){
return null;
}
ListNode slow=head;//慢指针
ListNode fast=head;//快指针
ListNode cur=head;
//通过循环判断链表是否带环
while(fast!=null&&fast.next!=null){
fast=fast.next.next;
slow=slow.next;
if(fast==slow){
//表示链表带环,结束循环
break;
}
}
//判断上述while循环结束的原因,只有两个原因
//第一个原因:如果快指针走到了链表结尾,则返回null
if(fast==null||fast.next==null){
return null;
}
//第二个原因:链表带环
//如果链表带环,则 快慢指针相遇的结点 和 链表头结点 距离链表入环的第一个结点是相同的
//所以只需要同步遍历,直到第一次相遇既为链表入环的第一个结点
while(cur!=fast){
cur=cur.next;
fast=fast.next;
}
return fast;
}