试图让我的算法运行到O(n)运行时

时间:2018-01-17 22:35:00

标签: java algorithm

因此,在我的高级算法类中,我们要为程序编写一个算法,以便在两个排序的整数数组中找到两个数字。格式为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++;
}

3 个答案:

答案 0 :(得分:5)

解决方案1:

B中的所有值添加到Map,其中B值作为地图键,B-index作为地图值。

迭代A,并将所需的B值计算为B = x - A。在地图中查找,如果找到,则可以获得索引。

每次只会迭代AB。向map添加单个值是 O(1),并且查找值为 O(1),假设为HashMap,因此整体为 O(n)的

解决方案2:

迭代A升序,B降序。

对于A中的每个值,请查看当前的B值。向下走B直到A + B <= x(或者到达B的开头)。

您每次只会迭代AB,所以 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);
}