求解三角形总数时使用for和while的区别

时间:2018-12-21 04:58:05

标签: java algorithm time-complexity

我在Codility中遇到了这个问题。参见此link。我设法解决了这个问题。但是,这给我留下了一个问题。

这是使用三个for的代码。

public int solution(int[] A) {
    Arrays.sort(A);
    int k, count = 0;
    for (int i = 0; i < A.length - 2; i++){
        for (int j = i + 1; j < A.length - 1; j++){
            for (k = j + 1; k < A.length; k++){
                if (A[i] + A[j] > A[k]) break;
            count += k - j - 1;
        }
    }
    return count;
}

这是在最里面的while中使用for的代码。

public int solution(int[] A) {
    // write your code in Java SE 8
    Arrays.sort(A);
    int k, count = 0;
    for (int i = 0; i < A.length - 2; i++){
        k = i + 2;
        for (int j = i + 1; j < A.length; j++){
            while (k < A.length && A[i] + A[j] > A[k]) {
                k++;
            }
            count += k - j - 1;
        }
    }
    return count;
}

上面的第一个解决方案在Codility方面得分不高,因为在大型测试用例中编译需要花费大量时间。但是,在第二个使用while的解决方案中,我得到了满分。即使我在上面的两个代码中都进行了三角形检查,为什么仍会如此呢? forwhile与这些有关系吗?

我也从第二个解决方案中了解了时间复杂度。这是linkk变量的初始化方式有所不同。这种差异是否会对这两个代码的性能产生巨大影响?

我正试图弄清楚这两个代码之间有什么区别。

2 个答案:

答案 0 :(得分:1)

for loopwhile loop与上述解决方案无关。实际上,我们可以修改第二个解决方案以使while循环为for循环,如下所示:

 public int solution(int[] A) {
        Arrays.sort(A);
        int k, count = 0;
        for (int i = 0; i < A.length - 2; i++) {
            k = i + 2;
            for (int j = i + 1; j < A.length; j++) {
                for( ; k < A.length; k++) {
                    if ( (A[i] + A[j]) <= A[k]) break;
                }
                count += k - j - 1;
            }
        }
        return count;
    }

实际上,两种解决方案的主要逻辑完全不同。

第一个解决方案:
我们将使用三个for循环来修复每个可能的三元组,并在前两个最小长度对的总和小于或等于第三个最小对时即断开"if (A[i] + A[j] <= A[k]) break;",然后中断第三个循环。因此,整体时间复杂度将为O(n^3)

第二种解决方案:
我们仅修复两个for loops并执行计算。代码中的while循环使用for loop对于每个i仅运行一次。由于数组已排序一次,因此该解决方案的思想是,如果我们使用前两个for loops配对两个值,并且索引ij上的值之和为{{1 }}即sum,如果它在索引sum = A[i] + A[j]处遇到一个大于或等于k的值,则对于下一个对sumi,第三索引肯定会大于先前的j + 1,因为索引k的值大于索引j + 1j的值。因此,第三个索引应该绝对在上一个A[j] <= A[j + 1]的右边。因此,第二个解决方案的总体复杂度为k

答案 1 :(得分:0)

在第二种解决方案中,k永远不会在第二层循环中减小。

因此,第一个解决方案的时间复杂度为O(n ^ 3),而第二个解决方案的时间复杂度为O(n ^ 2),