配列を指定して nums
正の整数の、配列の接頭辞の最長の可能な長さを返し nums
、それに登場している全ての数は出現数が同じになるように、このプレフィックスから正確に一つの要素を削除することが可能であるように、。
一つの要素を削除した後に何の残りの要素が存在しない場合、まだ、すべての数がocurrences(0)の同じ数を持って登場していると考えています。
例1:
入力:NUMSの= [2,2,1,1,5,3,3,5] 出力:7 説明:サブアレイのために[2,2,1,1,5,3,3]長さ7の、我々はNUMSを削除する場合は[4] = 5、我々は[2,2,1,1,3,3]を取得します、そのように、各番号は正確に2回表示されます。
例2:
入力:NUMSの= [1,1,1,2,2,2,3,3,3,4,4,4,5] 出力:13
例3:
入力:NUMSの= [1,1,1,2,2,2] 出力:5
例4:
入力:NUMSの= [10,2,8,9,3,8,1,5,2,3,7,6] 出力:8
制約:
2 <= nums.length <= 10^5
1 <= nums[i] <= 10^5
コンテストの中にあなたのソリューション。
ランタイムは空間が同様にO(N)であり、O(N)です。しかし、HashMapのとHashSetのは、単純な配列マッピングほど速くはありません。
クラスソリューション{ 公共 のint maxEqualFreq(INT [] NUMS){ int型 RES = nums.length。 // M1:数- >その周波数 地図<整数、整数> M1 = 新しい HashMapの<> (); // 平方メートル:周波数- >この周波数を持っているすべての数字。 地図<Integer型、セット<整数>>平方メートル= 新しい HashMapの<> (); // INIT M1 ため(INT i = 0; iはnums.lengthを<; iは++ ){ m1.put(NUMS [I]、m1.getOrDefault(NUMS [I]、 0)+ 1 )。 } // INIT M2 のための(INT K:m1.keySet()){ int型 V = m1.get(K)。 もし(!m2.containsKey(m1.get(K))){ m2.put(V、新しい HashSetの<> ()); } m2.get(V)は(k)を.add。 } // それは要件を満たしている場合、最長可能プレフィックスから始まる、確認してください。それがない場合は、結果として、現在のプレフィックス長を返します。 // そうでない場合は、両方のマップから現在の番号を削除し、それに応じて二つのマップを更新します。 // 私たちは現在の接頭辞のウィンドウに1つのまたは2のユニークな周波数を持っている場合にのみ、可能な有効な解決策があります。 // 2つの周波数:1つの以上出現して、単一の番号をそのすべての残りの部分の数字または1つの出現を持つ単一の番号。 // 1つの周波数:すべての数1つの出現を伴うまたは唯一の番号が存在する ため(; RES> 1; res-- ){ 場合(m2.size()== 2 ){ int型 MAXK = 0、ミンク= Integer.MAX_VALUEで、 用(int型K:m2.keySet()){ MAXK = Math.max(MAXK、K)。 minKを = Math.min(ミンク、K)。 } もし(MAXK -ミンク== 1 && m2.get(MAXK).size()== 1 ||ミンク== 1 && m2.get(minKを).size()== 1 ){ 破ります。 } } そう であれば(m2.size()== 1 ){ int型 onlyK = 0 。 用(int型K:m2.keySet()){ onlyK = K。 } もし(onlyK == 1 || m2.get(onlyK).size()== 1 ){ 破ります。 } } INT oldFreq = m1.get(NUMS [RES - 1 ])。 int型 newFreq = oldFreq - 1 。 m1.put(NUMS [RES - 1 ]、newFreq)。 m2.get(oldFreq).remove(NUMS [RES - 1 ])。 もし(m2.get(oldFreq).size()== 0 ){ m2.remove(oldFreq)。 } もし(newFreq> 0 ){ 場合(!m2.containsKey(newFreq)){ m2.put(newFreq、新しい HashSetの<> ()); } m2.get(newFreq).add(NUMS [RES - 1 ])。 } } リターンのres; } }
はるかに良いとクリーンなソリューション。
CNT [I]:番号iの出現。
FREQ [J]:Jの同じ出現を共有し、異なる数の合計数。
MAXF:処理されたすべての数字の最大周波数。唯一の現在の訪問数がMAXFを変更することがあります。
上記の溶液と同じ、我々が考慮すべき4例があります。
1.すべての数値は正確に一度だけ表示されます。MAXF == 1
2.唯一の1の数は、現在実行中のウィンドウに表示されますがあります。MAXF == I + 1
1つの番号が一度表示された以外3.すべての数字は、max_F時間が表示されます。MAXF * FREQ [MAXF] + 1 == I + 1
4.すべての数値はmax_Fを出現 - 1回、1つの回数がMAXF回表示されます除いて。(MAXF - 1)* FREQ [MAXF - 1] + MAXF == I + 1
[ - 1 MAXF] = 0の場合1は、実際にFREQがケース4の特別な場合です。
ここでのトリックは私たちが処理したすべての数字の合計数は、現在実行中のウィンドウと同じ長さであるかどうかを確認することです。私たちは、計算を行うために、最大周波数を使用しているため、この作品理由があります。2つ以上が、私たちの計算で最大周波数を使用すると、常に現在のウィンドウよりも大きい長さを生成した場合、我々は持つことができる唯一の異なる周波数は最大で2です。
クラスソリューション{ 公共 のint maxEqualFreq(INT [] A){ INT = [] CNT 新しい INT [100001]、FREQ = 新しい INT [100001 ]。 int型 MAXF = 0、RES = 0 ; 以下のために(int型 i = 0; iはA.lengthを<; iは++ ){ int型 NUM = A [i]は、 CNT [か] ++ ; FREQ [CNT []か -1] - 。 FREQ [CNT [NUM]] ++ ; MAXF = Math.max(MAXF、CNT [NUM])。 もし(MAXF == 1 || MAXF * FREQ [MAXF] + 1 == I + 1 ||(MAXF - 1)* FREQ [MAXF - 1] + MAXF == I + 1 ){ RES = I 1 + 。 } } リターンのres; } }