LeetCode - 環形鏈表 II

題目鏈接:https://leetcode-cn.com/problems/linked-list-cycle-ii/

題目描述

給定一個鏈表,返回鏈表開始入環的第一個節點。 如果鏈表無環,則返回
爲了表示給定鏈表中的環,我們使用整數pos來表示鏈表尾連接到鏈表中的位置(索引從 0 開始)。 如果pos-1,則在該鏈表中沒有環。
說明: 不允許修改給定的鏈表。

示例1:

輸入: head = [3,2,0,-4], pos = 1
輸出: tail connects to node index 1
解釋: 鏈表中有一個環,其尾部連接到第二個節點。

示例1

示例2:

輸入: head = [1,2], pos = 0
輸出: tail connects to node index 1
解釋: 鏈表中有一個環,其尾部連接到第一個節點。

示例2

示例3:

輸入: head = [1], pos = -1
輸出: no cycle
解釋: 鏈表中沒有環。

示例3

進階:
你是否可以不用額外空間解決此題?

我的思路

  • 首先使用快慢指針(fast&slow)判斷鏈表是否有環
    圖解1
  • 如果有環,如上圖。因爲使用了快慢指針,假設兩指針相遇於D點,因此fast比slow走的路程多一倍
  • 則此時快指針走的路程爲 S1 = AB + BCDEB + BCD (BCDEB表示一圈,字母順序表示方向)
  • 慢指針走的路程爲 S2 = AB + BCD
  • 由於 S1 = 2 × S2
  • => S1 = AB + BCDEB + BCD = 2 × (B + BD) ===(1)
  • => S2 = AB + BCD = BCDEB ===(2)
  • 證明了慢指針此時剛好走完全部路徑的一圈
  • 題目要求輸出B點這一入環點,有
  • DEB = BCDEB - BCD ===(3)
  • 聯立(1)(2)(3),得出
  • AB = DEB ===(4)
  • 說明D到B的距離和A到B的距離相等
  • 因此可以得出一種解決辦法:慢指針(或者快指針)從點D開始向前走DEB的距離,和一個新指針從A點開始走,兩個點會在B點相遇,這個B點就是我們需要的 入口點
    代碼如下:
/**
 * 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;
        }
        bool hasCircle = false;
        ListNode *fast = head;
        ListNode *slow = head;
        while(fast->next != NULL && fast->next->next != NULL){
            fast = fast->next->next;
            slow = last->next;
            if(fast == slow){
                hasCircle = true;
                break;
            }
        }
        if(hasCircle){---

L || head -> next == NULL){
            return NULL;
        }
        bool hasCircle = false;
        ListNode *fast = head;
        ListNode *slow = head;
        while(fast->next != NULL && fast->next->next != NULL){
            fast = fast->next->next;
            slow = last->next;
            if(fast == slow){
                hasCircle = true;
                break;
            }
        }
        if(hasCircle){
            ListNode *temp = head;
            while(temp != slow){
                temp = temp->next;
                slow = slow->next;
            }
            return temp;
        }
        else return NULL;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章