CSDN トピック チャレンジ フェーズ 2
参加トピック:アルゴリズム ソリューション
記事ディレクトリ
トピックのリンクと説明
https://leetcode.cn/problems/missing-two-lcci/
キーワード: インプレース ハッシュの合計 XOR
最初の反応は再び激しく解決します。分類後、2 つかかりますが、時間が足りません
方法 1: 合計
- 1 ~ n のすべての合計は、算術差分の公式を使用して取得できます。
- 数値を走査すると、2 桁が欠けても合計を取得できる
- 2 つの数値の減算は、探している 2 つの数値の合計です
- sum/2、左側と右側の 2 つの数値の中央の値を取得できます。
- 同様に、算術差分公式に従って 1-sum/2 の和を求めることができます。
- 1-sum/2 配列で合計を見つけることもできます。
- 2 つの数値を減算して左側の数値を取得し、合計すると左側の数値が右側の数値になります
スクリーンショットを実行する
コード
public int[] missingTwo(int[] nums) {
int n = nums.length + 2;
long sum = 0;
for (int x: nums) sum += x;
long sumTwo = n * (n + 1) / 2 - sum;
long limits = sumTwo / 2;
sum = 0;
for (int x: nums)
if (x <= limits) sum += x; // 两个数不相同那么一个大于,一个小于
long one = limits * (limits + 1) / 2 - sum;
return new int[]{
(int)one, (int)(sumTwo - one)};
}
方法 2: XOR
原理は合計と似ており、XOR (同じは 0、異なるは 1) が使用されます。
- a xor a = 0
- XOR は算術結合に従います (1-n XOR 1-n XOR (欠落 2 ビット = 2 欠落ビットの XOR))。
- a xor b xor b = a
- a xor b = c および a xor b xor a=c xor a、つまり b = c xor a
- 次に、最後に欠落している 2 つの XOR を取得します。下位ビットを通じて、1 つは 1、もう 1 つは 0 でなければなりません (そうでない場合、2 つの数値は等しい)。その後、すべてのメンバーの前の 2 つの XOR が繰り返されます。境界を介して、そのうちの 1 つが次のようになります。次に、前の結果と XOR して別の結果を取得します
スクリーンショットを実行する
コード
public int[] missingTwo(int[] nums) {
int n = nums.length + 2;
int xor = 0;
for (int v : nums) {
xor ^= v;
}
for (int i = 1; i <= n; ++i) {
xor ^= i;
}
int diff = xor & (-xor);
int a = 0;
for (int v : nums) {
if ((v & diff) != 0) {
a ^= v;
}
}
for (int i = 1; i <= n; ++i) {
if ((i & diff) != 0) {
a ^= i;
}
}
return new int[] {
a, xor ^ a};
}
方法 3: インプレース ハッシュ
配列の添え字と値のマッピングを通じて、何も交換されず、最終的に 1 回の走査後に欠落している数値が取得されます。これは、前の問題の解決策と一致しています。
スクリーンショットを実行する
コード
public int[] missingTwo(int[] nums) {
int[] hash = new int[nums.length+2];
for(int i = 0 ; i < nums.length;i++){
hash[nums[i]-1]++;
}
//hash记录
int[] re = new int[2];
int i = 0;
for(int j = 0 ; j < hash.length;j++){
//把0排除在外
if(hash[j] == 0){
re[i++] = j+1;
}
}
return re;
}
終わり
この質問を 100 個見つけるのは少し簡単です
コメント エリアでのコミュニケーション、毎日チェックイン、お急ぎください。!!