137. 一度だけ現れる数字Ⅱ
空ではない整数の配列を指定すると、各要素は 1 つの要素を除いて 3 回出現します。1 回だけ出現する要素を見つけます。
説明:
アルゴリズムは線形時間計算量を持つ必要があります。余分なスペースを使わずに実行できますか?
分析する
このコードはleetcodeの質問を参考に書いたものですが、私の理解に基づいてコードの出所を分析してみます。
このコードの時間計算量は O(n)、空間計算量は O(1) です。
まずトピックを分析します。空ではない整数配列。1 回出現する 1 つの要素を除き、他の要素は 3 回出現します。1 回出現する要素を見つけます。
つまり、1 回と 3 回出現する要素を区別する必要がありますが、トラバースする場合は 1 つずつトラバースする必要があるため、1 回と 3 回出現する要素の検出に加えて、中間状態も存在します。それは2回現れます。合計 3 つの状態があるため、2 つの 2 進数で表されます: 01、10、00 はそれぞれ 1 回、2 回、3 回出現する要素の状態を表します
。元の配列) 次
を満たす演算方法を見つける必要があります:
00 は 1 に遭遇して 01 になり、01 は 1 に遭遇して 10 になり、10 は 1 に遭遇して 00 になり、0 は変化しない
真理値表
XY | Z | Xnew | イニュー |
---|---|---|---|
00 | 0 | 0 | 0 |
01 | 0 | 0 | 1 |
10 | 0 | 1 | 0 |
00 | 1 | 0 | 1 |
01 | 1 | 1 | 0 |
10 | 1 | 0 | 0 |
XY: 元の状態
Z: 入力値
ここでの私の理解は、 1 は一般的な用語であり、3 つの状態の表現から、 Xnew = 1 は 2 回出現する数値を意味することがわかります (当然、out なので、 -of-order 配列、前の入力が満たされていない場合、3 つすべてが満たされ、状態がクリアされた場合、2 回出現する数値はここでは表されません); 同様に、Ynew = 1 は 1 回出現する数値を表します。
計算論理式: (Ynew = 1 の行を追加)
Ynew = (~X) Y (~Z)+ (~X) (~Y) Z = (~X) [Y ( ~Z) + (~Y) Z ] = (~X) (Y^Z)
Xnew = (~Ynew) (X^Z)
class Solution {
public int singleNumber(int[] nums) {
int sinceOne = 0,sinceTwo = 0;
// String resOne,resTwo;
for(int num : nums){
// resOne = Integer.toBinaryString(sinceOne);
// resTwo = Integer.toBinaryString(sinceTwo);
// System.out.println("resone:"+resOne);
// System.out.println("restwo:"+resTwo);
// System.out.println(" ");
sinceOne = ~sinceTwo & (sinceOne ^ num);
sinceTwo = ~sinceOne & (sinceTwo ^ num);
}
// resOne = Integer.toBinaryString(sinceOne);
// resTwo = Integer.toBinaryString(sinceTwo);
// System.out.println("resone:"+resOne);
// System.out.println("restwo:"+resTwo);
return sinceOne;
}
}
出典: LeetCode
リンク: https://leetcode-cn.com/problems/single-number-ii
著作権は LeetCode Network に属します。営利目的での転載の場合は正式な許諾を得た方へ、非営利での転載の場合は出典を明記の上、ご連絡ください。
推論を導き出してみる
この記事を 1 回しか出現しない特定の要素を除いて、他の要素はそれぞれ 4 回出現するように変更すると、1 回だけ出現する要素を見つけます。
状態は次のとおりです: 0 回、1 回、2 回、3 回:
00、01、10、11 の
真理値表に対応する 2 ビットのバイナリで表すことができます。
XY | Z | Xnew | イニュー |
---|---|---|---|
00 | 0 | 0 | 0 |
01 | 0 | 0 | 1 |
10 | 0 | 1 | 0 |
11 | 0 | 1 | 1 |
00 | 1 | 0 | 1 |
01 | 1 | 1 | 0 |
10 | 1 | 1 | 1 |
11 | 1 | 0 | 0 |
Ynew = ( X)Y( Z) + XY(~Z) + ( X)( Y)Z + X(~Y)Z = ( X)[Y( Z) + (~Y)Z] + X[Y (~Z) + (~Y)Z] = (~X)(Y^Z) + X(Y^Z) = (Y^Z) Xnew = X^Z 論理式から次のことがわかり
ます
。一度出現する Y のみを使用して表します。これは、1 回と 2 回を区別する質問の答えと同じです。