找到A [i] * A [j]>的阵列中的对数。 A [i] + A [j]

时间:2014-07-17 11:17:39

标签: java c++ c arrays algorithm

例如如果数组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)解决方案,而不使用额外的空间。我正在寻找。

2 个答案:

答案 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)

由于问题中没有明确说明,我将在下面做出以下两个假设:

  • 镜像对只计算一次(否则(b,a)是另一个有效对,如果(a,b)是,因此会增加有效对的数量)
  • 条目不得使用两次(例如(3.01,3.01)不是有效对)

两种假设都可以通过代码的小变化来改变。

A已排序,因为A1A2已排序。 对于一个小例子,这看起来像下面的

#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;
}

输出8. http://ideone.com/LaV9Cy

这是O(n)并且有效,因为A[i+1] > A[i],如果第二个(A[i+1] - 1) * (A[j] - 1) > (A[i] - 1) * (A[j] - 1) > 1成立则>。因此,我们可以简单地在我们找到的两个极值之间添加元素数量(result += j-i;),而不是单独尝试所有这些元素。