リンクリストが与えられたら、リンクリストにリングがあるかどうかを判断します。
リンクリストに次のポインタを継続的に追跡することで再び到達できるノードがある場合、リンクリストにリングがあります。特定のリンクリスト内のリングを表すために、整数posを使用して、リンクリストの終わりがリンクリストに接続されている位置を示します(インデックスは0から始まります)。posが-1の場合、リンクリストにリングはありません。注:posは、リンクリストの実際の状況を識別するためだけに、パラメーターとして渡されることはありません。
リンクリストにリングがある場合は、trueを返します。それ以外の場合は、falseを返します。
問題解決のアイデア:
1。高速ポインター高速と低速ポインター低速の2つのポインターを作成します。
2.低速ポインタを一度に1ステップ、高速ポインタを一度に2ステップ移動させます。
slow = slow->next;
fast = fast->next->next;
3.リングがある場合、速いポインターは遅いポインターに追いつきます。
コード
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool hasCycle(ListNode *head) {
//设置快慢指针slow,fast
ListNode* slow = head,*fast = head;
while(fast && fast->next)
{
slow = slow->next;//慢指针每次走一步
fast = fast->next->next;//快指针每次走俩步
if(fast == slow)
{
return true;
}
}
return false;
}
};
これを見ると、質問がある人もいるかもしれませんが、なぜ2ステップ早くポインタに追いつくことができるのでしょうか。3歩、4歩、n歩の場合、追いつくことができますか?
私の答えは次のとおりです。3ステップ、4ステップ、またはnステップが追いつく可能性がありますが、追いつかない可能性があり、サイクルは続行されます。
次に、波を分析しましょう。
遅いポインタがループに入るとき、速いと遅いの間の距離がxで
あり、速いと遅いが行くたびに、それらの間の距離が1ステップ減少するとします。
xが0に減少して交わるまで、x-1、x-2、x-3、...になります。
fastが3ステップかかる場合、距離xは
x-2、x-4、...です
。xが奇数の場合、fastは低速でスキップし、一致しません。スキップした後もギャップは奇数であり、無限ループが発生します。
これは、N歩歩くのと似ていますが、無限ループでもあります。