天天看点

LeetCode_LinkedList_142. Linked List Cycle II 环形链表 II(C++/Java)【快慢指针】

目录

​​一,题目描述​​

​​英文描述​​

​​中文描述​​

​​二,解题思路​​

​​三,AC代码​​

​​C++​​

​​Java​​

​​四,解题过程​​

​​第一博​​

一,题目描述

英文描述

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the next pointer. Internally, pos is used to denote the index of the node that tail's next pointer is connected to. Note that pos is not passed as a parameter.

Notice that you should not modify the linked list.

Example 1:

LeetCode_LinkedList_142. Linked List Cycle II 环形链表 II(C++/Java)【快慢指针】
Input: head = [3,2,0,-4], pos = 1 Output: tail connects to node index 1 Explanation: There is a cycle in the linked list, where tail connects to the second node.

中文描述

给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。

说明:不允许修改给定的链表。

进阶:

你是否可以使用 O(1) 空间解决此题?

示例 1:

LeetCode_LinkedList_142. Linked List Cycle II 环形链表 II(C++/Java)【快慢指针】

输入:head = [3,2,0,-4], pos = 1

输出:返回索引为 1 的链表节点

解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

LeetCode_LinkedList_142. Linked List Cycle II 环形链表 II(C++/Java)【快慢指针】

输入:head = [1,2], pos = 0

输出:返回索引为 0 的链表节点

解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

LeetCode_LinkedList_142. Linked List Cycle II 环形链表 II(C++/Java)【快慢指针】

输入:head = [1], pos = -1

输出:返回 null

解释:链表中没有环。

提示:

  • 链表中节点的数目范围在范围 [0, 10^4] 内
  • -10^5 <= Node.val <= 10^5
  • pos 的值为 -1 或者链表中的一个有效索引

来源:力扣(LeetCode)

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

二,解题思路

基于这一题​​@&再见萤火虫&【LeetCode_LinkedList_141. Linked List Cycle 环形链表(C++/Java)【快慢指针】】​​

假设慢指针速度为1,快指针速度为2,从最一般的角度看,有如下规律:
LeetCode_LinkedList_142. Linked List Cycle II 环形链表 II(C++/Java)【快慢指针】

慢指针slow经过路程a走到B点时,快指针fast经过2a走到C点,其中假设B点为环的起始点;

由于快指针比慢指针速度大一,所以经过x次移动后,两指针相遇(假设慢指针不动,快指针相对速度为1,且快指针距离慢指针为x,故得出结论),由于每次慢指针移动一位,所以相遇时如图:

LeetCode_LinkedList_142. Linked List Cycle II 环形链表 II(C++/Java)【快慢指针】

因此,从相遇点D到环的起点B距离为a,等于起点A到B的距离;

也就是说,在相遇之后,将其中一个指针放在起点,另一个指针仍在相遇点(由于是离散模型,具体算法实现时可能有小偏差,比如相遇点指针需要向前移动一位才能保证再次相遇),移动相同距离后再次相遇,相遇点就是环的起点。

三,AC代码

C++

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        if(head == NULL || head->next == NULL) return NULL;
        ListNode *slow = head, *fast = head->next;
        while(fast->next != NULL && fast->next->next != NULL && fast != slow) {
            slow = slow->next;
            fast = fast->next->next;
        }
        if(slow != fast) return NULL;
        slow = head;
        fast = fast->next;
        while(slow != fast) {
            slow = slow->next;
            fast = fast->next;
        }
        return slow;
        
    }
};      

Java

/**
 * 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) {
        if(head == null || head.next == null) return null;
        ListNode slow = head;
        ListNode fast = head.next;
        while(fast.next != null && fast.next.next != null && !(slow.equals(fast))) {
            slow = slow.next;
            fast = fast.next.next;
        }
        if(!(slow.equals(fast))) return null;
        slow =head;
        fast = fast.next;
        while(!(slow.equals(fast))) {
            slow = slow.next;
            fast = fast.next;
        }
        return slow;
    }
}      

四,解题过程

第一博