给定大小为100000的数组arr
,每个元素0 <= arr[i] < 100
。 (未排序,包含重复)
找出(i,j,k)
存在多少个三元组arr[i] ^ arr[j] ^ arr[k] == 0
注意:^
是Xor运算符。还0 <= i <= j <= k <= 100000
我有一种感觉,我必须计算频率并使用频率进行一些计算,但我似乎无法开始。
任何比明显的O(n^3)
更好的算法都是受欢迎的。 :)
这不是家庭作业。 :)
答案 0 :(得分:4)
我认为关键是你不需要识别i,j,k,只计算多少。
初始化数组大小100
循环arr,计算每个值的数量 - O(n)
循环遍历小数组的非零元素,计算出满足条件的三元组 - 假设所涉及的三个数字的计数是A,B,C - 原始arr中的组合数是(A + B + C)/!甲!乙!!C - 100 ** 3次操作,但假设100是固定值,那仍然是O(1)。
所以,O(n)。
答案 1 :(得分:1)
可能的O(n ^ 2)解决方案,如果有效:维护变量count
和两个数组single[100]
和pair[100]
。迭代arr
,并为值n
的每个元素:
count
:count += pair[n]
pair
:迭代数组single
并为索引x
的每个元素和值s != 0
执行pair[s^n] += single[x]
single
:single[n]++
最后count
保留结果。
答案 2 :(得分:1)
可能的O(100 * n)= O(n)解。 它解决问题i&lt; = j&lt; = k。 如您所知,A ^ B = 0&lt; =&gt; A = B,所以
long long calcTripletsCount( const vector<int>& sourceArray )
{
long long res = 0;
vector<int> count(128);
vector<int> countPairs(128);
for(int i = 0; i < sourceArray.size(); i++)
{
count[sourceArray[i]]++; // count[t] contain count of element t in (sourceArray[0]..sourceArray[i])
for(int j = 0; j < count.size(); j++)
countPairs[j ^ sourceArray[i]] += count[j]; // countPairs[t] contain count of pairs p1, p2 (p1 <= p2 for keeping order) where t = sourceArray[i] ^ sourceArray[j]
res += countPairs[sourceArray[i]]; // a ^ b ^ c = 0 if a ^ b = c, we add count of pairs (p1, p2) where sourceArray[p1] ^ sourceArray[p2] = sourceArray[i]. it easy to see that we keep order(p1 <= p2 <= i)
}
return res;
}
抱歉我的英语不好......
答案 3 :(得分:0)
Sort the array, keeping a map of new indices to originals. O(nlgn)
Loop over i,j:i<j. O(n^2)
Calculate x = arr[i] ^ arr[j]
Since x ^ arr[k] == 0, arr[k] = x, so binary search k>j for x. O(lgn)
For all found k, print mapped i,j,k
O(n ^ 2 lgn)
答案 4 :(得分:0)
以保罗建议的每个数字出现次数的频率计数开始。这会产生一个长度为100的数组freq []。
接下来,不是从该数组循环三元组A,B,C并测试条件A ^ B ^ C = 0,
在A对B上循环,A&lt; B.对于每个A,B,计算C = A ^ B(使得现在A ^ B ^ C = 0),并验证A
Sum+=freq[A]*freq[B]*freq[C]
对于频率计数,工作是O(n),对于A&lt;乙
由于三个不同的数字A,B,C中的每三个必须以某种顺序出现,因此每次发现每个这样的三次。接下来,你将不得不寻找两个数字相等的三元组。但是如果两个数字相等并且其中三个的xor为0,则第三个数字必须为零。因此,这相当于频率计数阵列上的B的二次线性搜索,计算(A = 0,B = C <100)的出现。 (在这种情况下要非常小心,特别注意B = 0的情况。计数不仅仅是freq [B] ** 2或freq [0] ** 3.隐藏在那里有一点组合学问题。)< / p>
希望这有帮助!
答案 5 :(得分:0)
我有一个(简单的)O(n ^ 2 log n)解决方案,它考虑到i,j和k引用索引而不是整数这一事实。
简单的第一遍允许我们构建一个包含100个值的数组A:values - &gt;索引列表,我们将列表排序以供以后使用。 O(n log n)
对于每对i,j使得i <= j,我们计算X = arr [i] ^ arr [j]。然后,我们在A [X]中执行二分搜索以定位索引k的数量,使得k> = j。 O(n ^ 2 log n)
我找不到任何方法来利用排序/计数算法,因为它们会消除索引要求。