因此,在我的高级算法类中,我们要为程序编写一个算法,以便在两个排序的整数数组中找到两个数字。格式为A [i] + B [j] == x。算法的运行时间需要为O(n)。 我以为我有它想要检查所以我给我的教授发了电子邮件,她告诉我我的运行时间是O(n ^ 2)。这是我的代码:
int[] A = {1,2,3,4,5};
int[] B = {1,2,3,4,5,6};
int x = 4;
int i = 0;
int j = 0;
for(int n = 0; n < (A.length*B.length); n++) {
if(i >= A.length)
i = 0;
if(n % B.length == 0)
j++;
if(A[i] + B[j] == x) {
System.out.println(A[i] + " + " + B[j] + " = " + x);
break;
}
i++;
}
修改
如果仍然不正确,我会道歉。我从未真正理解过Big-Oh的概念。这会将运行时改为O(n)吗?我摆脱了A.length * B.length并尝试了一些不同的东西。
int[] A = {1,2,3,4,5};
int[] B = {1,2,3,4,5};
int x = 5;
int i = 0;
int j = 0;
while(i < A.length) {
if(B[j] == x - A[i]) {
/* exit */ }
if(j >= B.length) {
j = 0;
i++; }
j++;
}
答案 0 :(得分:5)
解决方案1:
将B
中的所有值添加到Map
,其中B值作为地图键,B-index作为地图值。
迭代A
,并将所需的B
值计算为B = x - A
。在地图中查找,如果找到,则可以获得索引。
每次只会迭代A
和B
。向map添加单个值是 O(1),并且查找值为 O(1),假设为HashMap
,因此整体为 O(n)的
解决方案2:
迭代A
升序,B
降序。
对于A
中的每个值,请查看当前的B
值。向下走B
直到A + B <= x
(或者到达B
的开头)。
您每次只会迭代A
和B
,所以 O(n)。
解决方案2需要更少的内存(没有地图),并且可能更快(没有花时间构建地图)。
更新以下是代码:
以上描述基于对值索引的需求,每个解决方案的代码为:
解决方案1
private static void findSum(int[] a, int[] b, int x) {
Map<Integer, Integer> bIdx = new HashMap<>();
for (int j = 0; j < b.length; j++)
bIdx.put(b[j], j);
for (int i = 0; i < a.length; i++) {
Integer j = bIdx.get(x - a[i]);
if (j != null)
System.out.println("a[" + i + "] + b[" + j + "] = " + a[i] + " + " + b[j] + " = " + x);
}
}
解决方案2
private static void findSum(int[] a, int[] b, int x) {
for (int i = 0, j = b.length - 1, sum; i < a.length && j >= 0; i++) {
while (j >= 0 && (sum = a[i] + b[j]) >= x) {
if (sum == x)
System.out.println("a[" + i + "] + b[" + j + "] = " + a[i] + " + " + b[j] + " = " + x);
j--;
}
}
}
测试
int[] a = {1,2,3,4,5};
int[] b = {1,2,3,4,5,6};
findSum(a, b, 4);
输出(两者都相同)
a[0] + b[2] = 1 + 3 = 4
a[1] + b[1] = 2 + 2 = 4
a[2] + b[0] = 3 + 1 = 4
解决方案1使用Set
如果您不需要索引位置,则Set
更适合解决方案1:
private static void findSum(int[] aArr, int[] bArr, int x) {
Set<Integer> bSet = new HashSet<>();
for (int b : bArr)
bSet.add(b);
for (int a : aArr)
if (bSet.contains(x - a))
System.out.println(a + " + " + (x - a) + " = " + x);
}
输出
1 + 3 = 4
2 + 2 = 4
3 + 1 = 4
答案 1 :(得分:0)
以下是您如何衡量时间的示例,我已经提供了另一种方法来查找您提到的数字。查看运行时的差异:
int[] A = {1,2,3,4,5};
int[] B = {1,2,3,4,5,6};
int x = 4;
int i = 0;
int j = 0;
long t1 = System.nanoTime();
for(int n = 0; n < (A.length*B.length); n++) {
if(i >= A.length)
i = 0;
if(n % B.length == 0)
j++;
if(A[i] + B[j] == x) {
System.out.println(A[i] + " + " + B[j] + " = " + x);
break;
}
i++;
}
long t2 = System.nanoTime();
System.out.println("Time 1: "+(t2-t1));
//Here's the other method
long t3 = System.nanoTime();
for (int n = 0;n<B.length;n++){
for (int m =0;m<A.length;m++){
if(A[m]+B[n]==x){
System.out.println(A[m] +" + "+B[n] +" = "+ x);
}
}
}
long t4 = System.nanoTime();
System.out.println("Time 2: "+(t4-t3));
答案 2 :(得分:0)
以下是我想出的安德烈亚斯解决方案1的代码:
int[] A = {2,3,4};
int[] B = {7,9};
Map<Integer, Integer> hashMap = new HashMap<Integer, Integer>();
int x = 10;
int b;
for(int i = 0; i < B.length; i++) {
hashMap.put(B[i], i);
}
for (int n = 0; n < A.length; n++){
b = x - A[n];
if(hashMap.get(b) != null)
System.out.println(A[n] + " + " + b + " = " + x);
}