Leetcode Leetcode インタビューの質問 17.19. 消えた 2 つの数字

CSDN トピック チャレンジ フェーズ 2
参加トピック:アルゴリズム ソリューション

ここに画像の説明を挿入

トピックのリンクと説明

https://leetcode.cn/problems/missing-two-lcci/

キーワード: インプレース ハッシュの合計 XOR

最初の反応は再び激しく解決します。分類後、2 つかかりますが、時間が足りません

方法 1: 合計

  1. 1 ~ n のすべての合計は、算術差分の公式を使用して取得できます。
  2. 数値を走査すると、2 桁が欠けても合計を取得できる
  3. 2 つの数値の減算は、探している 2 つの数値の合計です
  4. sum/2、左側と右側の 2 つの数値の中央の値を取得できます。
  5. 同様に、算術差分公式に従って 1-sum/2 の和を求めることができます。
  6. 1-sum/2 配列で合計を見つけることもできます。
  7. 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 個見つけるのは少し簡単です

コメント エリアでのコミュニケーション、毎日チェックイン、お急ぎください。

おすすめ

転載: blog.csdn.net/qq_35530042/article/details/127058743