例如如果数组A是
A[0] = 0.1
A[1] = 0.6
A[2] = 1.2
A[3] = 1.7
A[4] = 3.5
然后对于对(3,4)我们有A[3]*A[4] > A[3]+A[4]
我想在数组中找到这样的对的数量。
另外A[i] = A1 [i] + A2[i]/1,000,000
A1和A2是给定的输入, A1和A2按排序顺序。
使用O(n ^ 2)算法回答是微不足道的。我被告知有O(n)解决方案,而不使用额外的空间。我正在寻找。
答案 0 :(得分:4)
x * y > x + y
除以x * y(正值)
1/x + 1/y < 1
让第一个光标(R)指向右边的元素(最小1 / a [i]值),第二个光标(L)指向左边的元素。
将L向右移动直到倒数之和达到1
添加(R-L)结果。
步骤R到左边。
重复移动L,直到R和L相遇为止
两个游标最多移动N步,因此算法需要O(N)
答案 1 :(得分:2)
由于问题中没有明确说明,我将在下面做出以下两个假设:
两种假设都可以通过代码的小变化来改变。
A
已排序,因为A1
和A2
已排序。
对于一个小例子,这看起来像下面的
#include <iostream>
#include <vector>
using namespace std;
int main()
{
std::vector<double> A({0.1,0.15,0.25,0.29,0.35,0.55,0.65,0.85,1.15,1.44,1.46,1.59,1.88,2.01,2.04,2.05,3.01});
size_t i=0, j=A.size()-1;
int result = 0;
if (A[j] <= 2) return 0;
while (i != j) {
if (A[i]*A[j]>A[i]+A[j]) {
result += j-i;
cout << A[i] << " to " << A[j] << " for a total of " << result << endl;
--j;
} else {
++i;
}
}
return 0;
}
这是O(n)
并且有效,因为A[i+1] > A[i]
,如果第二个(A[i+1] - 1) * (A[j] - 1) > (A[i] - 1) * (A[j] - 1) > 1
成立则>
。因此,我们可以简单地在我们找到的两个极值之间添加元素数量(result += j-i;
),而不是单独尝试所有这些元素。