算法性能。我无法解决它

时间:2018-02-26 04:27:51

标签: java algorithm

我试图解决算法问题,但我认为我的解决方案性能不佳。所以,如果有人能提供帮助,我将非常感激。

问题是:我有3个阵列A,B,C。我想知道每个B [i]和C [i]的范围内有多少元素。

Example:
A = [1,3,5,8]
B = [3,8]
C= [7,8]

So for B[0] and C[0] the answer is 2, because 3 and 5 are within range
and for B[1] and C[1] the answer is 1, because 8 are within range

the result has to be an array of [2,1].

Specifications:
B.length == C.length
B[i] <= C[i]

我试过这样解决这个问题:

static int[] method(int[] A, int[] B, int[] C) {
    Arrays.sort(A);
    int[] result = new int[B.length];
    for (int i = 0; i < B.length; i++) {
        int x = B[i];
        int y = C[i];
        int init = -1;
        int end = -1;
        for (int j = 0; j < A.length; j++) {
            int a = A[j];
            if (a >= x && init == -1) {
                init = j;
            }
            if (a == y && end == -1) {
                end = j;
            }
            if (a > y && end == -1) {
                end = j - 1;
            }
            if (init != -1 && end != -1) {
                break;
            }
        }
        result[i] = end - init + 1;
    }
    return result;
}

你们有什么想法?

4 个答案:

答案 0 :(得分:1)

最佳程序取决于A和B的大小。

如果A与B相比非常大,最好不要对它进行排序。遍历A的所有元素,并且对于每个元素,如果它们包含元素,则检查所有间隔。这给出了O(len A * len B)

的运行时间

另一方面,如果有很多区间,最好对A进行排序并使用二进制搜索来查找每个区间的开始和结束索引。这给出了O的运行时间(len A * log(len A)+ len B * log(len A))。

答案 1 :(得分:0)

这里你使用java8

public static int[] doTask(int[] A, int[] B, int[] C) {
    // Arrays.sort(A);

    List<Integer> aList = Arrays.stream(A).boxed().collect(Collectors.toList());

    int result[]=new int[B.length];
    for (int i=0; i < B.length; i++) {
        Integer b = B[i];
        Integer c = C[i];
        List<Integer> aList2 = aList.stream().filter(a -> a >= b && a <= c).collect(Collectors.toList());
        result[i] = aList2.size();
    }

    // System.out.println(result);
    return result;
}

result = [2,1]

答案 2 :(得分:0)

1) Concatenate the array A with B[i] & C[i]. i.e
   new array will be [1,3,5,8,3,7]
2) Sort the new array.
   sorted array [1,3,3,5,7,8]
3) filter out the elements between B[i] & C[i] from the array.
   filtered array [3,3,5,7]

答案 3 :(得分:0)

为了给Henry的答案添加一些东西,当有很多数字时,二进制搜索算法是最好的。此外,您的解决方案似乎没有考虑A中的重复值。

功能齐全的代码:

static int[] method2(int[] A, int[] B, int[] C) {
    Arrays.sort(A);
    int[] result = new int[B.length];
    for (int i = 0; i < B.length; i++) {
        int posMin = java.util.Arrays.binarySearch(A, B[i]);
        int posMax = java.util.Arrays.binarySearch(A, C[i]);
        if (posMin < 0) { posMin = -(posMin+1);   }
        if (posMax < 0) { posMax = -(posMax+1)-1; }
        result[i] = posMax - posMin +1;
    }
    return result;
}

从我用100个间隔和100万个样本进行的测试。

方法= 16368ms

方法2 = 433ms