Java 查找数组中的对数,其中A[i]*A[j]>;A[i]+;A[j]

Java 查找数组中的对数,其中A[i]*A[j]>;A[i]+;A[j],java,c++,c,arrays,algorithm,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]/1000000 其中A1和A2是给定的输入,A1和A2是按顺序排序的 用O(n^2)算法回答是很简单的。我被告知有O(n)的解决方案,而不使用额外的空间。我正在寻找答案。由于问题中没有明确说明这一点,我将在以下方面做出以下两个假设:

例如,如果数组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]/1000000

其中A1和A2是给定的输入,A1和A2是按顺序排序的


用O(n^2)算法回答是很简单的。我被告知有O(n)的解决方案,而不使用额外的空间。我正在寻找答案。

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

  • 镜像对仅计数一次(否则(b,a)是另一个有效对,如果(a,b)是,则会增加有效对的数量)
  • 条目不得使用两次(例如,(3.01,3.01)不是有效的一对)
这两种假设都可以通过代码的微小变化来改变

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;
}
#包括
#包括
使用名称空间std;
int main()
{
std::向量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});
尺寸i=0,j=A.size()-1;
int结果=0;
如果(A[j]A[i]+A[j]){
结果+=j-i;

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

  • 镜像对仅计数一次(否则(b,a)是另一个有效对,如果(a,b)是,则会增加有效对的数量)
  • 条目不得使用两次(例如,(3.01,3.01)不是有效的一对)
这两种假设都可以通过代码的微小变化来改变

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;
}
#包括
#包括
使用名称空间std;
int main()
{
std::向量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});
尺寸i=0,j=A.size()-1;
int结果=0;
如果(A[j]A[i]+A[j]){
结果+=j-i;
库特
除以x*y(对于正值)

1/x+1/y<1
让我们将第一个光标(R)指向右元素(最小1/a[i]值),第二个光标(L)指向左元素。
向右移动L,直到倒数之和达到1。
将(R-L)添加到结果中。
向左走R步。
重复移动L,直到R和L相遇

两个游标最多移动N步,因此算法需要O(N)

除以x*y(对于正值)

1/x+1/y<1
让我们将第一个光标(R)指向右元素(最小1/a[i]值),第二个光标(L)指向左元素。
向右移动L,直到倒数之和达到1。
将(R-L)添加到结果中。
向左走R步。
重复移动L,直到R和L相遇


两个游标最多移动N步,因此算法需要O(N)

O(N)算法来查找排序数组中的对数,其中A[i]*A[j]>A[i]+A[j]是无符号或有符号的数字?@mch无符号数字我想我有一个解决方案,首先是重新排列不等式,给出
(A[i]-1)*(A[j]-1)>1
但我能想到的最好的方法是
O(n log n)
。不过我认为这是正确的开始方式。你认为的O(nlogn)解决方案是什么?O(n)算法在排序数组中查找A[I]*A[j]>A[I]+A[j]的对数这些数字是无符号的还是有符号的?@mch unsigned numbers我想我有了一个解决方案,首先重新排列不等式,给出
(a[I]-1)*(a[j]-1)>1
,但我能想到的最好方法是
O(n log n)
。我认为这是正确的开始方式。O(nlogn)是什么你认为的解决方案?我有一个类似的想法。但是,我用
{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}尝试了你的解决方案
。不起作用。结果应该是20,但你的结果是8。@DavidWallace问得好。出于某种原因,这对我来说更直观。我可能已经习惯了使用迭代器。你也可以使用
I
j
。@gexicide
8
是第一个
+=p2-p1
给出的数字(介于
1.15
3.01
之间的元素),第二个元素将给出另外两个(
2.01
2.05
)。如果你想拥有对称对(有效地计算每对两次,因为(a,b)=(b,a))并且你有你的20,那么你可以将其乘以2。@example:你的意思是什么“第二个将得到另外两个”?简单地复制粘贴您的算法将得到8,这是错误的。因此,您的代码似乎不包含“第二个”“。我有一个奇怪的怀疑,那行递增的
result
应该是
result+=p2-p1+1;
但我现在不确定-因为我对这个问题有很多错误的想法。我有一个类似的想法。但是,我用
{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}
。不起作用。结果应该是20,但你的结果是8。@DavidWallace问得好。出于某种原因,这对我来说更直观。我可能已经习惯了使用迭代器。你也可以使用
I
j
。@gexicide
8
是第一个
+=p2-p1
给出的数字(介于
1.15
3.01
之间的元素),第二个元素将给出另外两个(
2.01
2.05
)。如果你想拥有对称对(有效地计算每对两次,因为(a,b)=(b,a))并且你有你的20,那么你可以将其乘以2。@example:你的意思是什么“第二个将得到另外两个”?简单地复制粘贴您的算法将得到8,这是错误的。因此,您的代码似乎可以
1/x + 1/y < 1