设A是n个正整数的数组,k是给定的整数。
我正在寻找算法来查找数组中是否有一对元素
A[i] * A[j] == k
和A[i] == A[j] + k
。如果有这样的一对,算法应该返回它们的索引。
这是一项家庭作业,我们被告知有一个O(n * log(n))解决方案。
答案 0 :(得分:3)
Sort the array. Also build a permuted index array by initializing an auxiliary array to 0, 1, 2 ... n and swapping indices every time you swap elements in the array, Time O(nLog(n))
for each element a[i] in array, Time O(n)
Binary Search for (a) k / a[i] or (b) a[i] - k, if found, return index j from permuted index array, Time O(log(n))
答案 1 :(得分:3)
首先是我的头脑:
Make a Map<Integer, Integer>
for each number a in A:
if (k / a) is a key in the HashMap:
output the index of a, and HashMap.get(k/a)
else
HashMap.add(a, indexof(a))
所以遍历数组是O(n),而O(log n)在Map中查找键(假设你使用了TreeMap,HashMap在最好的情况下会更好,但在最坏的情况下更糟糕)
编辑:我想这只能回答a)但你明白了
答案 2 :(得分:2)
使用nlog(n)进行排序 然后通过阵列itterate 对于每个指数,我计算A [j]需要的是为了满足方程式 检查数组中是否有这样的值
O(nlogn)+ O(N)* O(logn)
= O(nlogn)
答案 3 :(得分:2)
这有点澄清了Graphics Noob的解决方案。
此外,它更像是O(N)(假设哈希不会让我们失望),而不是O(N * log(N))。
Result findMultiplicationIndices(int[] A, int[] B, int k)
{
HashMap<Integer,Integer> aDivisors = new HashMap<Integer,Integer>();
for(int i=0;i<A.length;i++)
{
int a = A[i];
if(a!=0)
{
int d = k/a;
if(d*a == k)
aDivisors.put(d, i);
}
}
for(int i=0;i<B.length;i++)
{
Integer ai = aDivisors.get(B[i]);
if(ai != null)
return new Result(ai, i);
}
return null;
}
答案 4 :(得分:0)
如果k是固定的,那么有限多个整数x,y使得x * y = k。 对于每个因子(x,y),遍历列表查找A [i] = x或A [i] = y。 总运行时间= O(n)*#因子k = O(n)(确定性地,不是关于散列的假设)
问题表明A [i]都是正的,所以k也可以用有限多种方式分解x + y = k,所以O(n)也是如此。