LeetCode-142

循環リンクリスト

リンクリストを指定して、リンクリストがループに入り始める最初のノードを返します。リンクリストにリングがない場合は、nullが返されます。

アイデア:高速ポインタと低速ポインタ、高速ポインタは一度に2ステップ、低速ポインタは一度に1ステップ、リングがある場合、高速ポインタはリング内の低速ポインタに追いつきます

/**
 * 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) {
    
    
		ListNode *slow = head, *fast = head;
		while(fast && fast->next)
		{
    
    
			slow = slow->next;
			fast = fast->next->next;
			if(slow == fast)      //如果链表存在环
			{
    
    
				fast = head;
				while(fast != slow)//第二次相遇即为环的入口
				{
    
    
					fast = fast->next;
					slow = slow->next;
				}
				return fast;
			}
		}
		return NULL;
	}
};

题解

ここに画像の説明を挿入
このうち、[*]は高速ポインタと低速ポインタが最初に出会うポイント、リングに入る前の距離は[D]、低速ポインタがリングに入った後の移動距離は[S1]、残りの距離はリングは[S2]です

最初の遭遇
1.遅いポインターS = D + S12
。速いポインターF = D + n(S1 + S2)+ S1 n> = 1の場合、速いポインターは少なくとも複数の円を歩いた後に出会う可能性があり
ます3.またF = 2Sであるため、低速ポインタは1ステップ、高速ポインタは2ステップかかります
。4。1、2を代入して2(D + S1)= D + n(S1 + S2)+ S1
を取得しますさまざまなシフト項目を取得できます。 D =(n-1)S1 + nS2 =(n-1)(S1 + S2)+ S2
5.ここで、nは高速ポインターの回転数
n = 1 D = S2
n = 2 D = 1回転+ S2
n = 3 D = 2ターン+ S2

実際、何周するかは関係ありません。nラップ+ S2がエントリポイントであることがわかります
。6 衝突の機会を人為的に構築し、クイックポインタを開始させます再び(ただし、今回は一度に1ステップずつ)スローポインターがリング内を何度回っても、リングの位置。

参考記事
LeetCodeリンク

おすすめ

転載: blog.csdn.net/GreedySnaker/article/details/115114112
おすすめ