【问题标题】:Time Complexity Improvement时间复杂度改进
【发布时间】:2018-02-26 20:16:55
【问题描述】:

我一直在 Codility.com 上尝试编码挑战 这是我尝试的问题之一:

给出了一个由 N 个整数组成的非空零索引数组 A。一种 整数对 (P, Q),使得 0 ≤ P

例如,数组 A 满足:

A[0] = 4
A[1] = 2
A[2] = 2
A[3] = 5
A[4] = 1
A[5] = 5
A[6] = 8

包含以下示例切片:

切片(1, 2),其平均值为(2 + 2) / 2 = 2;切片 (3, 4),其 平均值为 (5 + 1) / 2 = 3;切片 (1, 4),其平均值为 (2 + 2 + 5 + 1) / 4 = 2.5。目标是找到平均值最小的切片的起始位置。

写一个函数:

类解决方案 { public int solution(int[] A); }

给定一个由 N 个整数组成的非空零索引数组 A, 返回具有最小平均值的切片的起始位置。 如果有多个切片具有最小平均值,您应该 返回此类切片的最小起始位置。

例如,给定数组 A 使得:

A[0] = 4
A[1] = 2
A[2] = 2
A[3] = 5
A[4] = 1
A[5] = 5
A[6] = 8

该函数应返回 1,如上所述。

我已经提交了我的答案并获得了 60%。我的解决方案是正确的,我通过了所有测试用例。我得到 60% 的原因是时间复杂度。对于大型测试用例,我的解决方案运行时间过长。

这是我在 Java 中的解决方案:

class Solution {
    public int solution(int[] A) {
        int size = A.length;

        if (size == 2) {
            return 0;
        }

        int sizeLessOne = size - 1;
        int start       = 0;
        double min      = 0;
        boolean isFirst = true;

        for (int i = 0; i < sizeLessOne; i++) {
            int val1  = A[i];
            for (int j = i + 1; j < size; j++) {
                int val2   = A[j];
                double avg = ((double) val1 + val2) / (j - i + 1);
                if (isFirst || avg < min) {
                    min   = avg;
                    start = i;
                    if (isFirst) {
                        isFirst = false;
                    }
                }
                val1 += val2;
            }
        }

        return start;
    }
}

public class SolutionRunner {
    public static void main(String[] args) {
        Solution s = new Solution();
        int[] A    = {4,2,2,5,1,5,8};
        System.out.println(s.solution(A));
    }
}

根据我的代码,由于嵌套的 for 循环,我最坏情况的时间复杂度是 O(N^2)。 O(N) 上的预期更坏情况。我不确定如何实现这一点。

提前致谢。

【问题讨论】:

  • 我不确定 O(N) 是否可行。您可以尝试分段树。这将为您提供 O(NlogN) 解决方案。

标签: java algorithm time complexity-theory


【解决方案1】:

您可以在O(n) 中执行此操作,因为始终存在大小为 2 或 3 的最佳子数组。

假设您有一个大小为n &gt; 3 的最佳子数组SS 可以分成两个子数组:大小为2S'size n - 2 &gt;= 2S''Avg(S') &gt;= Avg(S)Avg(S'') &gt;= Avg(S) 因为 S 是最优的。但是Avg(S) &gt;= min(Avg(S'), Avg(S'')),因此Avg(S) = Avg(S') = Avg(S'')。所以S'也是最优的。

【讨论】:

  • 嗨,我在试图理解这一点时遇到了一些麻烦。可以分享一个例子吗?
  • 假设你找到了一个大小为 4 的最小切片。让这个切片 S 定义为 [a, b, c, d], avg(S) = (a + b + c + d) / 4 . 你知道 avg(S) 是最小值,所以:avg(S) = avg(S1) 所以 avg(S) = avg(S1) = avg(S2) 意味着 S1 也是最优的。所以你不必寻找大小为 4 的最佳切片,因为它总是从大小为 2 的最佳切片开始。这个推理对于大小为 3 的切片不正确
  • 对于您的代码,这意味着您只需要检查大小为 2 和 3 的切片。这是 O(n)。我的例子并不是一个真正的例子,对于一个更实际的方法:你可以尝试构建一个大小为 4 的最佳切片,而不是从大小为 2 的最佳切片开始。
猜你喜欢
  • 2016-02-13
  • 2012-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多