Java 面接の質問 - 最初の n 個の数値の 2 進数形式の 1 の数

トピック: 負でない数値 n を入力し、0 から n までの各数値の 2 進数形式で 1 ​​の数を計算し、配列を出力してください。たとえば、入力 n は 4 です。バイナリ形式 0、1、2、3、4 の 1 の数はそれぞれ 0、1、1、2、1 であるため、出力配列 [0, 1, 1] 、2、1】

多くの人が最初に思いつく乱暴な解決策は、for ループを使用して、0 から n までの各整数 i のバイナリ形式で 1 ​​の数を取得することです。したがって、問題は、整数 i の 2 進数形式で 1 ​​の数を見つける方法に変換されます。

効率的な方法: 毎回「i & (i-1)」を使用して、整数 i の右端の 1 を 0 に変更します。整数 i から 1 が減算され、その右端の 1 が 0 になります。右側にまだ 0 がある場合、右側の 0 はすべて 1 になり、左側の 1 は 0 になります。2 進数 1100 を例にとると、1 を引いた結果は 1011 になります。これは、次のビット単位の AND 演算です。 1100 と 1011 ちょうど 1000 です。2 進数の 1100 の右端の 1 が 0 になり、結果はちょうど 1000 になります。

public int[] countBits(int num){
    int[] result = new int[num+1];//存储第i位1的数目
    for(int i = 0; i <= num; i++){
        int j = i;
        while (j !=0){//判断所有的1是否都转变为零
            result[i]++;
            j = j & (j -1);//将最后一个一的位置变为零
        }
    }
    return result;
}

コードの最適化: 分析の結果、「i & (i - 1)」は、i のバイナリ形式の右端の 1 を 0 に変更します。つまり、整数 i のバイナリ形式の 1 の数は、「i の数」よりも多いことがわかります。 & (i - 1) 「」の 2 進数形式の 1 の数は、それより 1 つ多くなります。

public int[] countBits(int num){
    int[] result = new int[num+1];//存储第i位1的数目
    for(int i = 0; i <= num; i++){
        result[i] = result[i & (i-1)] + 1;
    }
    return result;
}

別の方法: 「i/2」に従って i のバイナリ形式の 1 の数を計算します。

        正の整数 i が偶数の場合、i は「i/2」を 1 ビット左にシフトした結果と同等であるため、偶数 i と「i/2」の 2 進数形式の 1 の数は次のようになります。 " 同じです。i が奇数の場合、i は「i/2」を 1 ビット左にシフトしてから 1 を加算することと同じなので、奇数 i の 2 進数形式の 1 の数は「i/2」より 1 つ多くなります。 」。

public int[] countBits(int num){
    int[] result = new int[num+1];//存储第i位1的数目
    for(int i = 0; i <= num; i++){
        result = result[i>>1] + (i&1);
    }
    return result;
}

このコード スニペットでは、「i>>1」を使用して「i/2」を計算し、「i & 1」を使用して「i%2」を計算します。

おすすめ

転載: blog.csdn.net/lijingxiaov5/article/details/122187539