题目链接:LC 142. 环形链表Ⅱ
2020.10.10第一次解答:
解题思路
- 判断链表是否为环形链表。若是,用快慢指针返回环的长度(原理见一文搞定常见的链表问题),用于确定首个入环节点位置(末尾节点的 next 指针指向第一个入环节点)。若不是,返回0,代表链表非环形链表。
- 若非环形链表,返回nullptr。若为环形链表,用双指针确定首个入环节点。
C++代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
int isCycle(ListNode *head) {
ListNode *slow = head;
ListNode *fast = head;
while (fast) {
fast = fast->next;
if (fast) {
fast = fast->next;
}
if (fast == slow) { //获取环长度
int cnt = 0;
while (fast) {
cnt++;
fast = fast->next;
if (fast) {
fast = fast->next;
}
if (fast == slow) {
return cnt;
}
slow = slow->next;
}
}
slow = slow->next;
}
return 0;
}
ListNode *detectCycle(ListNode *head) {
int length = isCycle(head);
if (length == 0) return nullptr;
ListNode *slow = head;
ListNode *fast = head;
for (int i = 0; i <= length; i++) {
fast = fast->next;
}
while (fast != slow) {
fast = fast->next;
slow = slow->next;
}
return fast;
}
};
Java代码
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public int isCycle(ListNode head) {
if (head == null || head.next == null) return 0;
ListNode slow = head;
ListNode fast = head.next;
while (slow != fast) {
if (fast == null || fast.next == null) return 0;
slow = slow.next;
fast = fast.next.next;
}
//此时已确定链表有环,进而获取环长度
fast = fast.next;
int cnt = 1;
while (slow != fast) {
fast = fast.next;
cnt++;
}
return cnt;
}
public ListNode detectCycle(ListNode head) {
int length = isCycle(head);
if (length == 0) return null;
ListNode slow = head;
ListNode fast = head;
for (int i = 0; i < length; i++) fast = fast.next;
while (slow != fast) {
slow = slow.next;
fast = fast.next;
}
return fast;
}
}