是否可以编写一个函数,该函数接受一个 n 个整数数组和一个整数 k 并返回BITWISE OR值等于的数组元素对数 k 比O( n 2 )时间好吗?
示例:如果我们有一个数组= [21,10,29,8]并且k = 31,则该函数应返回2,因为有效对是(21,10)和(10,29)。 / p>
*为清楚起见* 21 OR 10 = 31,21 OR 29 = 29,21 OR 8 = 29,10 OR 29 = 31,10 OR 8 = 10,29 OR 8 = 29,因此答案为2。
**** k是一个常数,总是31。****
答案 0 :(得分:5)
假设时间单位是对跨越 k 的单词大小的基本运算,则O( n + k 2 )是可能的:
#include <stdio.h>
#include <stdlib.h>
#define NumberOf(a) (sizeof (a) / sizeof *(a))
static unsigned Count(size_t N, unsigned *A, unsigned k)
{
// Count number of elements with each pattern of bits in k.
unsigned *C = calloc(k + 1, sizeof *C);
if (!C) exit(EXIT_FAILURE);
for (size_t n = 0; n < N; ++n)
if ((A[n] & ~k) == 0) ++C[A[n]];
// Count number of solutions formed with different values.
unsigned T = 0;
for (size_t i = 0; i < k; ++i)
for (size_t j = i+1; j <= k; ++j)
if ((i | j) == k)
T += C[i] * C[j];
// Add solutions formed by same value (only possible when both are k).
T += C[k] * (C[k]-1) / 2;
free(C);
return T;
}
int main(void)
{
unsigned A[] = { 21, 10, 29, 8 };
printf("%u\n", Count(NumberOf(A), A, 31));
}
这可以简化为O( n + p 2 ),其中 p 是通过将每个数组元素压缩为刚好在 k 中设置的位(删除不在 k 中的位并将其余位移动为连续)。另外,可以改善计算组合的主循环,但我认为这不会影响O()时间。
答案 1 :(得分:1)
人们认为答案是“否”。
假设您的k
是2^s - 1
(因此它是二进制的111...111
),并且所有数字最多为k
。然后
a or b = k <=> (~a) and (~b) = 0.
,其中~
是“按位不”。例如
110 or 101 = 111 <=> 001 and 010 = 0
这是一个一般的正交向量问题(OVP),流行的猜想指出,它的求解速度不及O(n^2)
(我忽略了一些细节)。
请参见此处的猜想1:https://arxiv.org/pdf/1510.02824.pdf。