web-dev-qa-db-ja.com

サイクルリンクリストでサイクル開始ノードを見つける方法を説明してください。

亀とうさぎの会議はループの存在を終わらせることを理解していますが、うさぎを待ち合わせ場所に留めたままリンクされたリストの最初に亀を移動し、続いて両方を一度に移動すると、サイクルの開始点で会うことができますか?

142

これは、 サイクル検出のためのフロイドのアルゴリズム です。アルゴリズムの第2フェーズについて質問しています-サイクルの一部であるノードを見つけたら、どのようにしてサイクルのstartを見つけるのでしょうか?

フロイドのアルゴリズムの最初の部分では、ウサギはカメのすべてのステップで2ステップ移動します。カメとノウサギが出会うとサイクルが発生し、ミーティングポイントはサイクルの一部になりますが、必ずしもサイクルの最初のノードではありません。

カメとノウサギが出会うと、Xが最小となる最小のi(カメがとる歩数)を見つけました。 = X2i。 muがXから取得するステップ数を表すようにします サイクルの開始まで、ラムダがサイクルの長さを表すようにします。次に、i = mu + alambda、および2i = mu + blambdaです。ここで、aおよびbは、カメとウサギがサイクルを何回回ったかを示す整数です。最初の方程式を2番目の方程式から引くと、i =(b-a)* lambdaが得られるため、iはlambdaの整数倍になります。 したがって、Xi + mu = Xムー。バツ は、カメとウサギの待ち合わせ場所を表します。亀を開始ノードXに戻す場合、そしてカメとノウサギを同じ速度で続けさせます。追加のステップの後、カメはXに達します。ムー、ウサギはXに到達しますi + mu = Xムー、したがって、2番目のミーティングポイントはサイクルの開始を示します。

71
Jim Lewis

http://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare で提供されているサイクル検出アルゴリズムを自分の言葉で明確にしてみましょう。

drawing

仕組み

上記の図のように、リストの先頭を指すカメとウサギ(ポインターの名前)を循環させてみましょう。

カメを一度に1ステップ動かし、一度に2ステップウサギを動かすと、最終的にはカメが出会うという仮説を立てましょう。まず第一に、この仮説が正しいことを示しましょう。

図は、サイクルのあるリストを示しています。サイクルの長さはnであり、最初はmサイクルから離れています。また、ミーティングポイントがkサイクルの開始から離れており、亀がi合計ステップを踏んだときに亀と野ウサギが出会ったとしましょう。 (それまでに2i合計ステップをとったはずです。).

次の2つの条件が満たされる必要があります。

1) i = m + p * n + k

2) 2i = m + q * n + k

最初のものは、カメがiステップ移動し、これらのiステップで最初にサイクルに到達すると言います。次に、正の数pに対してp回のサイクルを実行します。最後に、ウサギと出会うまでk個以上のノードを調べます。

ウサギについても同様です。 2iステップ移動し、これらの2iステップで最初にサイクルに到達します。次に、正の数qに対してq回のサイクルを実行します。最後に、亀に会うまでk個以上のノードを調べます。

うさぎはカメの2倍の速度で移動するため、両方が待ち合わせ場所に到着すると時間は一定です。

そのため、単純な速度、時間、距離の関係を使用して、

2 ( m + p * n + k ) = m + q * n + k

=> 2m + 2pn + 2k = m + nq + k 

=>  m + k = ( q - 2p ) n

M、n、k、p、qのうち、最初の2つは指定されたリストのプロパティです。この式を真にするk、q、pの値のセットが少なくとも1つあることを示すことができれば、仮説が正しいことを示します。

そのようなソリューションセットの1つは次のとおりです。

p = 0

q = m

k = m n - m

これらの値が次のように機能することを確認できます。

m + k = ( q - 2p ) n  

=> m + mn - m = ( m - 2*0) n

=> mn = mn.

このセットでは、i

i = m + p n + k

=> m + 0 * n + mn - m = mn.

もちろん、これは必ずしも最小のiであるとは限りません。言い換えれば、カメとノウサギは何度も会ったことがあるかもしれません。ただし、少なくとも一度はある時点で出会うことを示しているため、仮説が正しいと言えます。そのため、1つを1ステップずつ移動し、もう1つを2ステップずつ移動すると、会議が必要になります。

これで、アルゴリズムの2番目の部分、つまりサイクルの始まりを見つける方法に進むことができます。

サイクル開始

カメとノウサギが出会ったら、リストの最初にカメを戻して、出会った場所でウサギを飼いましょう(サイクルの開始からkステップ)。

仮説は、同じ速度で移動させた場合(両方とも1ステップ)、最初に出会うのはサイクルの開始であるということです。

この仮説を証明しましょう。

最初に、Oracleがmが何であるかを教えてくれると仮定しましょう。

次に、m + kステップ移動させると、カメは最初に出会ったポイントに到着する必要があります(サイクルの開始からkステップ離れたところ-図を参照)。

以前は、m + k = (q - 2p) nであることを示しました。

M + kステップはサイクル長nの倍数であるため、平均でhareはサイクル(q-2p)回を通過し、同じポイントに戻ります(サイクル開始からkステップ)。

さて、m + kステップ移動させる代わりに、mステップのみ移動させた場合、カメはサイクルの始めに到着します。うさぎは、(q-2p)回転を完了するのにkステップ不足です。サイクル開始の前にkステップを開始したため、ノウサギはサイクル開始に到達する必要があります。

その結果、これは、彼らが最初にいくつかのステップの後に始まるサイクルで会わなければならないことを説明します(亀はmステップ後にサイクルに到着したばかりで、すでに中のウサギを見ることはできなかったためサイクル)。

これで、それらが出会うまでに移動する必要があるステップの数は、リストの先頭からサイクルの先頭までの距離であることがわかりました。もちろん、アルゴリズムはmが何であるかを知る必要はありません。彼らは会うまで、カメと野ウサギの両方を一度に1歩ずつ動かします。ミーティングポイントはサイクルの開始点であり、ステップ数はサイクルの開始点までの距離(m)でなければなりません。リストの長さを知っていると仮定すると、リストの長さからmを引くサイクルの長さを計算することもできます。

301
CEGRD

この画像を参照してください:

enter image description here

会議前にslowPointerが移動した距離= x + y

会議の前にfastPointerが移動した距離=(x + y + z)+ y = x + 2y + z

FastPointerはdoubleで移動するため、slowPointerの速度、およびtimeは一定です両方がミーティングポイントに到達したとき。

したがって、単純な速度、時間、距離の関係を使用して、2(x + y)= x + 2y + z => x + 2y + z = 2x + 2y => x = z

したがって、slowPointerをリンクリストの先頭に移動し、slowPointerとfastPointerの両方を一度に1つのノードに移動させることにより、彼らは両方とも同じ距離をカバーしています.

リンクリストでループが開始するポイントに到達します。

114
Old Monk

Old Monkのシンプルで劣勢の答え は、高速ランナーが完全なサイクルを1つだけ完了したときにサイクルを見つけることを説明します。この回答では、遅いランナーがループに入る前に、速いランナーがループを複数回実行した場合について説明します。


同じ画像を使用する: enter image description here

高速ランナーが低速と高速の出会いの前にループmを実行したとしましょう。この意味は:

  • 低速走行距離:x + y
  • 高速走行距離:x + m(y + z)+ yつまりextray彼らが出会う場所

高速は低速の2倍の速度で実行され、同じ時間実行されているため、低速で実行された距離を2倍にすると、高速で実行された距離になります。副<文>この[前述の事実の]結果として、それ故に、従って、だから◆【同】consequently; therefore <文>このような方法で、このようにして、こんなふうに、上に述べたように◆【同】in this manner <文>そのような程度まで<文> AひいてはB◆【用法】A and thus B <文>例えば◆【同】for example; as an example、

  • 2(x + y)= x + m(y + z)+ y

Xを解くと、

x =(m-1)(y + z)+ z

実際のシナリオでは、x=(m-1)完全なループの実行+追加の距離z

したがって、1つのポインターをリストの先頭に置き、もう1つをミーティングポイントに置いた場合、それらを同じ速度で移動すると、インループポインターが完了しますm-1 ループを実行し、ループの開始点でもう一方のポインターを満たします。

59
displayName

Figure 1

最初の衝突時に、カメは上記のようにm + kステップ移動しました。うさぎはカメの2倍の速さで動きます。つまり、うさぎは2(m + k)歩きます。これらの単純な事実から、次のグラフを導き出すことができます。

Figure 1

この時点で、カメを最初に戻し、ウサギとカメの両方が一度に1ステップずつ移動する必要があることを宣言します。定義では、mステップの後、カメはサイクルの開始点になります。うさぎはどこにいるの?

うさぎもサイクルの始まりになります。これは、2番目のグラフから明らかです。カメが最初に戻されたとき、ノウサギはk最後のサイクルに進みました。 mステップの後、ノウサギは別のサイクルを完了し、カメと衝突します。

7
skedastik

とても簡単です。相対速度の観点から考えることができます。ウサギが2つのノードを移動し、カメが1つのノードを移動する場合、カメウサギは1つのノードを移動します(カメが休んでいると仮定します)。したがって、循環リンクリスト内の1つのノードを移動すると、必ずその時点で再び会うことになります。

循環リンクリスト内の接続ポイントを見つけた後、問題は2つのリンクリスト問題の交点を見つけることになりました。

5
murali krish

アプローチ:

2つのポインターがあります。

  • 一度に1つのノードを移動する遅いポインター。
  • 一度に2つのノードを移動する高速ポインター。

2つのポインターが一致する場合、ループがあることが証明されます。一度会うと、ノードの1つが頭を指し、両方が一度に1つのノードを進めます。彼らは、ループの開始時に会います。

理由: 2人が円形のトラックを歩いているとき、1人は2倍の速度で、どこで会いますか?まさに彼らが始めた場所。

ここで、高速ランナーのkステップラップでnステップの有利なスタートがあるとします。彼らはどこで会いますか? n-kステップで正確に。スローランナーが(n-k)ステップをカバーすると、ファーストランナーはk+2(n-k)ステップをカバーします。 (ie、k+2n-2k stepsすなわち2n-k steps)。つまり、(n-k)ステップ(パスは循環型であり、その後のラウンドの回数は関係ありません。単にそれらが交わる位置に関心があります)。

そもそも、高速ランナーはどのようにしてkステップの先頭に立つことができましたか?スローランナーがループの開始に到達するまでに多くのステップを要したからです。したがって、ループの開始点はヘッドノードからkステップです。

注:両方のポインターが出会ったノードは、kループの開始点(ループ内)から離れており、ヘッドノードもkループ開始点から離れています。したがって、これらのノードからボットから1ステップの等間隔でポインターを進めると、ループの開始時にそれらが一致します。

簡単だと思います。あいまいな部分がある場合はお知らせください。

4
Aadith

さて、サイクルの開始からkステップ離れたポイントでウサギとカメが出会うと仮定しましょう。サイクルが始まる前のステップ数はmuで、サイクルの長さはLです。

だから今、ミーティングポイントで->

亀がカバーする距離= mu + a * L + k-式1

(サイクルの開始に到達するためのステップ+サイクルの「a」回の反復をカバーするために実行されるステップ+サイクルの開始からkステップ)(aは正の定数)

野ウサギがカバーする距離= mu + b * L + k-式2

(サイクルの開始に到達するためのステップ+サイクルの「b」回の反復をカバーするために実行されるステップ+サイクルの開始からkステップ)(bは正の定数であり、b> = a)

したがって、ノウサギによってカバーされる余分な距離は=式2-式1 =(b-a)* L

ウサギは亀の2倍の速さで動くため、この距離は開始点からの亀の距離にも等しいことに注意してください。これは、「mu + k」と同等であり、サイクルの複数のトラバーサルを含めない場合、開始点からミーティングポイントまでの距離でもあります。

したがって、mu + k =(b-a)* L

したがって、このポイントからmuステップはサイクルの開始に戻ります(サイクルの開始からkステップはすでにミーティングポイントに到達するために実行されているため)。これは、同じサイクルまたは後続のサイクルで発生する可能性があります。したがって、ここでカメをリンクリストの先頭に移動すると、サイクルの開始点に到達するまでmuステップがかかり、ウサギはサイクルの開始点に到達するまでmuステップを実行するため、両者はサイクルの開始点。

追伸正直なところ、元のポスターと同じ質問を心に抱き、最初の答えを読んで、いくつかのことを明らかにしましたが、最終結果を明確に得ることができなかったので、自分のやり方でそれを試してみました理解しやすい。

3
Prateek Jassal

enter image description here画像クレジット

ポインターがたどるリンクの数を呼び出し、スローポインターを1リンク、ファストポインターを2リンク移動するアルゴリズムの反復回数を計ります。長さCのサイクルの前にN個のノードがあり、サイクルオフセットk = 0〜C-1でラベル付けされています。

サイクルの開始に到達するには、スローにN時間と距離がかかります。これは、サイクル内で高速でNの距離を取ることを意味します(Nはそこに到達し、Nはスピンします)。そのため、時間Nで、低速はサイクルオフセットk = 0にあり、高速はサイクルオフセットk = N mod Cにあります。

N mod Cがゼロの場合、低速と高速は一致し、サイクルは時間Nとサイクル位置k = 0で見つかります。

N mod Cがゼロでない場合、高速は低速に追いつく必要があります。これは、Nがサイクル内のC-(N mod C)の距離です。

高速は低速の1ごとに2を移動し、反復ごとに距離を1減らすため、これには時間Nの高速と低速の距離(C-(N mod C))と同じくらいの追加時間がかかります。 slowはオフセット0から移動しているため、これはそれらが出会うオフセットでもあります。

したがって、N mod Cがゼロの場合、フェーズ1はサイクルの開始時にN回の反復後に停止します。そうでない場合、フェーズ1は、サイクルへのオフセットC-(N mod C)でN + C-(N mod C)の反復後に停止します。

// C++ pseudocode, end() is one after last element.

int t = 0;
T *fast = begin();
T *slow = begin();
if (fast == end()) return [N=0,C=0];
for (;;) {
    t += 1;
    fast = next(fast);
    if (fast == end()) return [N=(2*t-1),C=0];
    fast = next(fast);
    if (fast == end()) return [N=(2*t),C=0];
    slow = next(slow);
    if (*fast == *slow) break;
}

わかりましたので、フェーズ2:低速はサイクルに到達するためにさらにNステップを必要とし、その時点で高速(時間ステップごとに1移動)は(C-(N mod C)+ N)mod C = 0になります。フェーズ2の後のサイクルの開始時。

int N = 0;
slow = begin();
for (;;) {
    if (*fast == *slow) break;
    fast = next(fast);
    slow = next(slow);
    N += 1;
}

完全を期すために、フェーズ3では、サイクルをもう一度移動してサイクルの長さを計算します。

int C = 0;
for (;;) {
    fast = next(fast);
    C += 1;
    if (fast == slow) break;
}
2
Warren MacEvoy

enter image description here

図に示すようにポインターがポイントPで出会った場合、距離Z + YはポイントPであり、X + YはポイントPでもあり、Z = Xを意味します。 1つのポインターをPから移動し、別のポインターをstart(S)から一致するまで移動し続ける理由は、同じポイントM(Pからの距離ZとSからの距離Z)に等しい距離(ZまたはX)を移動することを意味しますループの開始。シンプル!

1
user9639921

問題をループ問題に減らし、最初の問題に戻る

次の説明はより直感的です。

  1. 頭から始まる2つのポインター(1= tortoiseと2= hare)を取る(O)、1のステップ長は12のステップ長は21がそのサイクルの開始ノード(A)に到達する瞬間を考えてください。

    次の質問「1がAにあるとき2はどこですか?」に答えたいと思います。

    したがって、OA = aは自然数(a >= 0)です。ただし、次のように記述できます:a = k*n + b、ここでa, k, n, b are natural numbers

    • n =サイクル長
    • k >= 0 =定数
    • 0 <= b <= n-1

    b = a % nを意味します。

    例:a = 20およびn = 8 => k = 2およびb = 4の場合20 = 2*8 + 4であるため。

    1でカバーされる距離はd = OA = a = k*n + bです。しかし同時に、2D = 2*d = d + d = OA + d = OA + k*n + bをカバーします。これは、2がAにある場合、k*n + bをカバーする必要があることを意味します。ご覧のとおり、kはラップの数ですが、それらのラップの後、2はAからbになります。 21がAにあるときです。そのポイントBを呼び出してみましょう。ここでAB = b

    enter image description here

  2. ここで、問題を円に減らします。問題は、「ミーティングポイントはどこですか?」です。それはどこC

    enter image description here

    すべてのステップで、2は、11であるため、1(メートルとしましょう) 12からさらに進んでいますが、同時に22によって1に近づいています。

    そのため、12の間の距離がゼロになるとき、交差点になります。これは、2n - bの距離を短縮することを意味します。これを達成するために、1n - bステップを作成し、22*(n - b)ステップを作成します。

    したがって、交点はA(時計回り)から遠く離れたn - bになります。これは、これが1で満たされるまでの距離であるためです2。 =>CAの間の距離は、CA = bAC = AB + BC = n - bであるため、CA = n - ACです。 ACの距離は簡単な数学的距離ではないため、AC = CAとは思わないでください。これは、AC(ここでAは開始点で、Cは終了点です)。

  3. それでは、最初のスキーマに戻りましょう。

    a = k*n + bCA = bを知っています。

    2つの新しいポインター1 '1' 'を使用できます。ここで、1'は先頭から始まります(O)および1 ''は交点(C)から始まります。

    1 'OからA1' 'CからAに進み、kラップを終了し続けます。したがって、交点はAです。

    enter image description here

    enter image description here

1

これに対する答えはすでにたくさんありますが、視覚的に直感的なこの図を思いつきました。おそらく他の人を助けることができます。

私にとっての主なアハモーメントは次のとおりです。

  • T(トータス)をT1(ループ前)とT2 (ループ中)。 T = tortoise, H = hare

  • THから減算します。残っている(H-T = H ')はTと等しい。

  • 残りの計算は非常に簡単です。 From H, subtract where T visually overlaps
0
mhelvens

-ループの前にkステップあります。 kが何であるかわからないので、調べる必要はありません。 kだけで抽象的に作業できます。

-kステップ後

----- Tはサイクル開始時

----- Hはサイクル内のkステップです(合計2kになり、kがループに入ります)。

**ループサイズになりました-k離れています

(k == K == mod(loopsize、k)-ノードが5ノードサイクルに2ステップである場合、7、12、または392ステップもあることに注意してください。要因で。

一方が他方の2倍の速度で移動しているため、単位時間あたり1ステップの速度で互いに追いつくため、loopsize-kで会います。

つまり、サイクルの開始点に到達するにはk個のノードが必要であるため、ヘッドからサイクルスタートまでの距離とサイクルスタートまでの衝突は同じです。

したがって、最初の衝突の後、Tを先頭に戻します。 TとHは、それぞれ1の割合で移動すると、サイクルスタートで会います。 (両方ともkステップ)

つまり、アルゴリズムは次のとおりです。

  • 頭の動きからT = t.nextとH.next.nextが衝突するまで(T == H)(サイクルがあります)

//ループの長さを計算することにより、k = 0またはTとHがループの先頭で出会った場合に注意する

-カウンターでTまたはHを動かしてサイクルの長さを数える

-ポインターT2をリストの先頭に移動します

-サイクルステップのポインター長を移動する

-別のポインターH2を先頭に移動

-T2とH2を、サイクルの開始時に会うまでタンデムに移動します

それでおしまい!

0
Droid Teahouse

彼らが出会うとそれが出発点になるというのは本当だとは思いません。はいループの開始時に終了します。例えば:

1->2->3->4->5->6->7->8->9->10->11->12->13->14->15->16->17->18->19->20->21->22->23->24->8

Meet at :16

Start at :8

public Node meetNodeInLoop(){

    Node fast=head;
    Node slow=head;

    fast=fast.next.next;
    slow=slow.next;

    while(fast!=slow){

        fast=fast.next;
        fast=fast.next;

        if(fast==slow) break; 

        slow=slow.next;
    }

    return fast;

}

public Node startOfLoop(Node meet){

    Node slow=head;
    Node fast=meet;

    while(slow!=fast){
        fast=fast.next;
        if(slow==fast.next) break;
        slow=slow.next;
    }

    return slow;
}
0
MrA

これを図で操作すると役立ちます。方程式なしで問題を説明しようとしています。

  1. ウサギとカメを輪になって走らせ、ウサギをカメに2回走らせると、ウサギの1ラップの終わりに半分になります。うさぎ亀の2周の終わりに1周し、2人が出会うことになります。これは、ウサギが3回走る場合、ウサギ1ラップがカメの1/3に等しい場合など、すべての速度に適用されます。
  2. ループのmステップ前にそれらを開始する場合、それはより速いウサギがループで先に開始していることを意味します。そのため、カメがループの開始点に到達した場合、ウサギはmステップ先のループであり、それらが出会うと、ループ開始のmステップ前になります。
0
shiva kumar

上記のすべての分析で、あなたが実例学習者である場合、私は他の誰もが説明しようとした数学を説明するのに役立つ短い分析と例を書き上げようとしました。さあ!

分析:

2つのポインターがあり、一方が他方よりも速く、一緒に移動すると、それらは最終的に再会してサイクルを示し、nullはサイクルなしを示します。

サイクルの開始点を見つけるには、...

  1. mは、頭からサイクルの開始までの距離です。
  2. dはサイクル内のノードの数です。
  3. p1は、より遅いポインターの速度です。
  4. p2は、より速いポインターの速度です。 2は、一度に2つのノードをステップスルーすることを意味します。

    次の反復を観察します。

 m = 0, d = 10:
 p1 = 1:  0  1  2  3  4  5  6  7  8  9 10 // 0 would the start of the cycle
 p2 = 2:  0  2  4  6  8 10 12 14 16 18 20

 m = 1, d = 10:
 p1 = 1: -1  0  1  2  3  4  5  6  7  8  9
 p2 = 2: -1  1  3  5  7  9 11 13 15 17 19

 m = 2, d = 10:
 p1 = 1: -2 -1  0  1  2  3  4  5  6  7  8
 p2 = 2: -2  0  2  4  6  8 10 12 14 16 18

上記のサンプルデータから、高速ポインターと低速ポインターが出会うときはいつでも、サイクルの開始からmステップ離れていることが簡単にわかります。これを解決するには、高速のポインターを先頭に戻し、速度を低速のポインターの速度に設定します。彼らが再び会うとき、ノードはサイクルの始まりです。

0
Steve

相対速度 の考え方を使用した簡単な説明-物理学101 /運動学の講義。

Circle in LinkedList

  1. リンクリストの開始から円の開始までの距離をxホップと仮定します。円の始点をポイントXとして呼び出しましょう(大文字で-上図を参照)。また、円の合計サイズをNホップと仮定します。

  2. ノウサギの速度= 2 *カメの速度。つまり、それぞれ1 Hops/sec2 Hops/secです

  3. カメが円Xの開始点に達すると、図のxのポイントでウサギをさらにYホップする必要があります。 (ウサギはカメの2倍の距離を移動したため)。

  4. したがって、XからYまでの時計回りの残りの弧の長さはN-xになります。 Thisはまた、うさぎとカメが出会うことができるように、うさぎとカメの間をカバーする相対距離でもあります。この相対的な距離は、時間t_m、つまり会う時間でカバーされるとしましょう。相対速度は(2 Hops/sec - 1 Hops/sec)、つまり1 Hops/secです。したがって、相対距離=相対速度X時間を使用すると、t = N-x秒が得られます。そのため、カメとウサギの両方の待ち合わせ場所に到達するには、N-xが必要です。

  5. N-x秒の時間と1 Hops/secの速度で、ポイントXで以前にいたカメが、ミーティングポイントMに到達するためのN-xホップをカバーします。つまり、ミーティングポイントMN-xにあることを意味します。X =から反時計回りにホップします(さらに意味します)=>ポイントxからMまで時計回りにXの距離が残っています。

  6. ただし、xは、リンクリストの先頭からポイントXに到達する距離でもあります。

  7. ここで、xのホップ数が何に対応するかは気にしません。 LinkedListの最初に1匹、亀をミーティングポイントMに1匹置き、ホップ/ウォークさせると、必要なポイント(またはノード)であるポイントXで会います。

0
Pranjal Mittal

まあ言ってみれば、

N[0] is the node of start of the loop, 
m is the number of steps from beginning to N[0].

2つのポインターAとBがあり、Aは1倍の速度で実行され、Bは2倍の速度で実行され、両方とも最初から開始されます。

aがN [0]に達すると、BはすでにN [m]にいるはずです。 (注:Aはmステップを使用してN [0]に到達し、Bはさらにmステップである必要があります)

次に、Aはさらにステップをk回実行してBに衝突します。つまり、AはN [k]に、BはN [m + 2k]にあります(注:BはN [m]から2kステップ実行する必要があります)

AはそれぞれN [k]およびN [m + 2k]でBに衝突します。これはk = m + 2kを意味するため、k = -m

したがって、N [k]からN [0]に戻るには、さらにmステップが必要です。

簡単に言うと、コリジョンノードが見つかった後、さらにmステップ実行するだけです。最初から実行するポインタとコリジョンノードから実行するポインタを持つことができます。それらはmステップ後にN [0]で会います。

したがって、擬似コードは次のとおりです。

1) A increase 1 step per loop
2) B increase 2 steps per loop
3) if A & B are the same node, cycle found, then go to 5
4) repeat from 1
5) A reset to head
6) A increase 1 step per loop
7) B increase 1 step per loop
8) if A & B are the same node, start of the cycle found
9) repeat from 6