リンク:https://leetcode-cn.com/problems/continuous-subarray-sum
アレイの負でない数と特定の整数kが与えられると、アレイは連続サブ配列を含むかどうかを判断する機能を記述し、少なくとも2のサイズは、合計Kの倍数、N * Kの、すなわち、合計であり、前記nは整数。
例1:
入力:[23,2,4,6,7]、K = 6
出力:真の
説明:[2,4]はサイズ2と6のサブ配列であり、そして。
例2:
入力:[23,2,6,4,7]、K = 6
出力:真の
説明:5と42、及びサイズを有する[23,2,6,4,7]サブアレイ。
説明:
配列の長さは万を超えていません。
あなたは、32ビット符号付き整数の範囲内のすべての数値の合計と考えることができます。
解決策1:暴力の最適化
そして第1のプレ接頭辞、および暴力は、すべての可能な目盛間隔[I、J]を列挙し、その後プレフィックスはどうか、N%K ==和次に判断を2つのセクションが減算によって得られました。Oの時間複雑(N2)
和= 0、K = 0は、それらが異常ゼロ除算かもしれないことに留意されたいです。
クラス解決{ パブリック: BOOL checkSubarraySum(ベクトル< INT >&NUMS、int型K){ int型 N = nums.size()。 ベクター < INT > pre_sum(N + 1 )。 以下のために(INT iが= 1 ; I <= N I ++ ){ pre_sum [I] + = pre_sum [I- 1 ] + NUMS [I- 1 ]。 } ため(INT iは= 0 ; iは<N- 1 ; I ++ ){ ため(INTJ = I + 1、J <nであり、j ++ ){ int型の和= pre_sum [J + 1 ] - pre_sum [I]。 もし(和== 0 ||(K &&和%K == 0))を返す 真。 } } を返す 偽。 } }。
解決策2:ハッシュテーブルは、問題のリードに依存しないソリューションをバックル----
この方法では、我々は、i番目の要素まで保存して蓄積するためにHashMapを使用して、我々はこのプレフィックスの残りの部分を取り、kで割ら。次の理由の場合:
我々は、和%kの現在位置まで記録する指定された配列、反復処理します。我々は新しい和%kの値を見つけたら(つまり、HashMapの中に値がない)、我々はレコードHashMapを挿入しようとする(合計%のK、I)
今、i番目の位置の仮定する和%kはレムです。任意の左端ポイントにサブアレイおよびiは、この例では、kの倍数である場合、位置jは、その後、ハッシュマップのj番目の要素の値に格納されている(REM + N * k)は%Kであり、ここでnはゼロより大きい整数。我々は、ハッシュマップで同じ値にi番目の要素と一緒に保存されている(REM + N * K)%K = REMを見つけます。
この観察に基づいて、我々は結論:合計%kの値がハッシュマップ内に配置されているたびには、kの整数倍であり、それらと要素の間に、2つのインデックスiおよびjを表します。そのため、同じ和%kのHashMapの限り、我々は直接Trueに戻ることができます。
クラス解決{ パブリック: BOOL checkSubarraySum(ベクトル< INT >&NUMS、int型K){ マップ < int型、整数 > ;融点 int型プリサム= 0 ; MP [ 0 ] = - 1。 // ? 以下のために(INT iが= 0 ; I <nums.sizeを(); I ++ ){ プリサム + = NUMS [I]。 // もし(K =!0)プリサム%= K; もし(1== mp.countは(プリサム)){ 場合(I-MP [プリサム]> 1) // 戻り 真。 } 他の MP [プリサム] = I。 } を返す 偽。 } }。