【问题标题】:Minimum Subarray which is larger than a Key大于键的最小子数组
【发布时间】:2013-06-13 23:20:03
【问题描述】:

我有一个整数数组(不一定是排序的),我想找到一个连续的子数组,它的值之和最小,但大于特定值K

例如:

输入:数组:{1,2,4,9,5},键值:10

输出:{4,9}

我知道在O(n ^ 2) 中执行此操作很容易,但我想在O(n) 执行此操作

我的想法:我在 O(n) 中无论如何都找不到这个,但我能想到的只是 O(n^2) 的时间复杂度。

【问题讨论】:

  • 数组可以有负数,还是只有非负数?
  • 假设它只能有正值。

标签: arrays algorithm computer-science


【解决方案1】:

假设它只能有正值。

那么就简单了。

解决方案是最小(最短)连续子数组之一,其总和为> K

取两个索引,一个作为子数组的开始,一个作为结束(一个结束),以end = 0start = 0 开始。初始化sum = 0;min = infinity

while(end < arrayLength) {
    while(end < arrayLength && sum <= K) {
        sum += array[end];
        ++end;
    }
    // Now you have a contiguous subarray with sum > K, or end is past the end of the array
    while(sum - array[start] > K) {
        sum -= array[start];
        ++start;
    }
    // Now, you have a _minimal_ contiguous subarray with sum > K (or end is past the end)
    if (sum > K && sum < min) {
        min = sum;
        // store start and end if desired
    }
    // remove first element of the subarray, so that the next round begins with
    // an array whose sum is <= K, for the end index to be increased
    sum -= array[start];
    ++start;
}

由于仅增加两个索引,因此算法为O(n)

【讨论】:

    【解决方案2】:

    在 O(n) 时间和 O(1) 空间内工作的正数和负数(不完全确定负数)的 Java 实现。

    public static int findSubSequenceWithMinimumSumGreaterThanGivenValue(int[] array, int n) {
    
        if (null == array) {
            return -1;
        }
    
        int minSum = 0;
        int currentSum = 0;
        boolean isSumFound = false;
        int startIndex = 0;
        for (int i = 0; i < array.length; i++) {
            if (!isSumFound) {
                currentSum += array[i];
                if (currentSum >= n) {
                    while (currentSum - array[startIndex] >= n) {
                        currentSum -= array[startIndex];
                        startIndex++;
                    }
                    isSumFound = true;
                    minSum = currentSum;
                }
            } else {
                currentSum += array[i];
                int tempSum = currentSum;
                if (tempSum >= n) {
                    while (tempSum - array[startIndex] >= n) {
                        tempSum -= array[startIndex];
                        startIndex++;
                    }
                    if (tempSum < currentSum) {
                        if (minSum > tempSum) {
                            minSum = tempSum;
                        }
                        currentSum = tempSum;
                    }
                } else {
                    continue;
                }
            }
        }
        System.out.println("startIndex:" + startIndex);
        return minSum;
    }
    

    【讨论】:

      猜你喜欢
      • 2012-10-12
      • 2014-08-07
      • 1970-01-01
      • 2013-06-04
      • 2017-04-16
      • 2016-05-27
      • 2016-12-28
      • 2016-12-20
      • 1970-01-01
      相关资源
      最近更新 更多