ここでのオリジナルタイトルリンク:https://leetcode.com/problems/circular-array-loop/
トピック:
あなたは、円形の配列を指定され nums
、正と負の整数のを。数の場合は kの 指標ではポジティブで、その後、前進 k個の ステップを。逆に、それは否定的だ場合( - k個)、後方に移動 k個の ステップを。配列が円形であるので、あなたは最後の要素の次の要素が最初の要素であり、最初の要素の前の要素が最後の要素であると仮定してもよいです。
ループ(又はサイクル)があるかどうかを決定します nums
。サイクルが開始し、同じインデックスと周期の長さ> 1.また、サイクルの動きは、すべて単一の方向に従わなければならないで終了しなければなりません。換言すれば、サイクルは、両方の前後の動きで構成されてはなりません。
例1:
入力:[2、-1,1,2,2-] 出力:真の 説明:インデックス0からサイクルは、あります- > 2 - > 3 - > 0のサイクルの長さは3です。
例2:
入力:[-1,2] 出力:偽の 説明:インデックス1からの移動- > 1 -サイクルの長さは、サイクルの長さが1以上でなければなりません定義では1であるため、> 1 ...、サイクルではありません。
例3:
入力:[-2,1、-1、-2、-2] 出力:偽 説明:インデックスから動き1 - > 2 - > 1 - > ...ではないサイクル、なぜならインデックス1から移動- >図2は、前進であるが、インデックス2から移動- > 1が後退です。サイクルのすべての動きは、単一の方向に従わなければなりません。
注意:
- -1000≤NUMS 1000年≤[I]
- NUMS [I]≠0
- 5000≤1≤nums.length
ファローアップ:
あなたはO(n)の時間計算量とO(1)余分なスペースの複雑さでそれを解決してもらえますか?
ソリューション:
ループがあるかどうかを確認するために、歩行者やランナーのポインタを使用してください。
私はNUMSを+とするたびに、ポインタの移動[I]。それが肯定的である場合、リターン/ nums.length(I [i]はNUMS + 1)。それが否定的である場合には、リターン/ nums.length + nums.length(私はNUMS [I]を+)。
同じ方向を維持するためには、各インデックスはすべて正またはすべて負のシフトを確認してください。
ウォーカー、ランナーが満たしている場合には、そのループがあります。
次の動きはまだここにいる場合でも、ループ内の単一の要素を回避するために場合に、確認してください。
現在のルーチンのためのループが存在しない場合、最後の、そして0として、このルーチンのすべてのNUMSをマークし、その後、これらの数字の重複calcuationがないでしょう。
時間計算:O(n)を。N = nums.length。
スペース:O(1)。
ACのJava:
1 クラスソリューション{ 2 公共 ブール circularArrayLoop(INT [] NUMS){ 3 であれば(NUMS == NULL || nums.length <2 ){ 4 リターン 偽。 5 } 6 7 ための(int型 i = 0; iがnums.lengthを<; Iは++ ){ 8 た場合(NUMS [I] == 0 ){ 9 続けます。 10 } 11 12 INTウォーカー= I。 13 int型のランナー= I; 14 一方(NUMS [I] * NUMS [シフト(ランナー、NUMS)]> 0 && NUMS [I] * NUMS [シフト(シフト(ランナー、NUMS)、NUMS)]> 0 ){ 15 ウォーカー= シフト(ウォーカーNUMS); 16 ランナー= シフト(シフト(ランナー、NUMS)、NUMS)。 17 // ループがある場合、歩行者とランナーが満たす 18を 場合(歩行者が== ランナー){ 19 // ループにおける唯一の要素が存在する場合ながら壊れ、 20 場合(歩行者== シフト(歩行者、NUMS)) { 21 ブレーク。 22 } 23 24 リターン 真; 25 } 26 } 27 28 // 現在のルーチンとはループが存在しない、 29 // マーク値0として、その後の重複計算が存在しないであろう 30 int型 IND = I。 31 INTヴァル= NUMS [IND]。 32 一方(ヴァル*のNUMS [IND]> 0 ){ 33 INT nextInd = シフト(IND、NUMS)。 34 NUMS [IND] = 0 ; 35 IND = nextInd。 36 } 37 } 38 39 リターン はfalse ; 40 } 41 42 プライベート int型のシフトを(int型、Iの値int {[] NUMS)を 43 INT N = nums.length。 44 リターン iがNUMS [I]> = 0 +?(iは+ NUMS [I])%のN:(iはNUMSを+ [I])%N + N。 45 } 46 }
同様のリンクリストサイクル。