これは、Google からの最近のインタビューの質問です。
f(X, Y) を、X と Y の 2 進数表現で対応する異なるビットの数として定義します。たとえば、2 と 7 の 2 進数表現はそれぞれ 010 と 111 であるため、f(2, 7) = 2 です。1 番目と 3 番目のビットが異なるため、f(2, 7) = 2 です。
N 個の正の整数、A1、A2、…、AN の配列が与えられます。1 ≤ i、j ≤ N となるすべてのペア (i, j) の f(Ai, Aj) の合計を求めます
例えば:
A=[1, 3, 5]
我々は返します
f(1, 1) + f(1, 3) + f(1, 5) + f(3, 1) + f(3, 3) + f(3, 5) + f(5, 1) + f (5, 3) + f(5, 5) =
0 + 1 + 1 + 1 + 0 + 2 + 1 + 2 + 0 = 8
O(n ^ 2)であるこのソリューションを考えることができました
int numSetBits(unsigned int A) {
int count = 0;
while(A != 0) {
A = A & (A-1);
count++;
}
return count;
}
int count_diff_bits(int a, int b)
{
int x = a ^ b;
return numSetBits(x);
}
for (i = 0; i < n; i++)
for (j = 0; j < n; j++) {
sum += count_diff_bits(A[i], A[j]);
}
}
私が考えることができる別のアプローチは次のとおりです(各要素には2進数が1つしか含まれていないことを考慮して):
- 配列の最後から開始
- これまでに見つかった 1 と 0 の数を保持する
- 現在の要素が 1 の場合
count_of_zeros
、最終的な合計に寄与します。 - 配列の先頭に到達するまで、このように続けます。
このアプローチは正しいですか。