我正在处理一个我无法找到任何教科书解决方案的面试问题。给定一个整数列表,找到任何连续值/子列表的最大总和不超过给定的K长度。
答案 0 :(得分:1)
设p [i]为前缀和a [0] + ... + a [i - 1]。我们可以在线性时间内轻松计算序列p。对于固定索引i,在索引i处具有其右边界的大多数K的子数组的最大总和可以计算为
MAX(j = max(0,i - K + 1)到i,p [i + 1] - p [j])= p [i + 1] - MIN(j = max(0,i - K + 1)到i,p [j])
我们可以按升序处理可能的右边界。然后,我们想要计算每个这样的i,在O(1)中的上述公式中的MIN项。这正是sliding window minimum问题,它使用特殊的队列数据结构有一个很好的解决方案。此队列支持以摊销的O(1)执行 push / pop 以及 min 的操作。使用它,我们的算法如下所示:
q = new MinQueue()
sum = 0
answer = 0
for i := 0 to N - 1:
q.push(sum) # sum == p[i]
if len(q) > K:
q.pop()
sum += a[i]
answer = max(answer, sum - q.min()) # sum == p[i + 1]
总运行时间是线性的。
答案 1 :(得分:0)
这是一个大纲。你有X [i,其中i = 1..N]数字。给定K,假设K <= N,则存在从1 ...(N-K + 1)开始的N-K + 1个子序列。您可以将总和存储在S [j,j = 1..N-K + 1]
中说,你已经有了S [j]。然后 S [j + 1] = S [j] -X [j-1] + X [j + K-1]。 你需要找到S [1],其余的都很简单。现在问题减少到找到S中的最大值。可以有1个或更多答案。复杂性线性。
HTH让你开始。
答案 2 :(得分:0)
它看起来类似于最大子阵列问题。参考_http://en.wikipedia.org/wiki/Maximum_subarray_problem_
var arr = [1,2,31,24,34,3,23,24,3,25,34,54,3,2,34];
var getSmallestSubSeqSum = function(arr, k){
var totalLength = arr.length, index = 0, sums= [];
for(index=0;index < totalLength-k+1;index++)
{
sums.push(0);
}
for(var index=0; index < totalLength-k+1;index++)
{
for(var aI = 0; aI < k; aI++)
{
sums[index] += arr[index + aI];
}
}
console.log('Total Length: ' + totalLength);
console.log('Sub Length: ' + 3);
console.log('sums length: ' + sums.length);
console.log("Array: "+arr);
index = Math.max.apply(Math, sums);
console.log('Max Sum: ' + index);
console.log("Sums: "+ sums);
index = sums.indexOf(index);
console.log("max sum sub array: " + arr.slice(index, index + k));
};
getSmallestSubSeqSum(arr, 6);
以上代码段应该有助于这是javascript。
答案 3 :(得分:0)
N个数是X [0],...... X [N-1]并且假设1 <= K <= N. S [i,l]代表从i开始并且长度不超过1的子列表的最大总和。
你有S [i,1] = X [i]然后S [i,l] = MAX(S [i + 1,l-1] + X [i],X [i]),其中L&GT; = 2
最终答案是MAX(S [i,K],其中i <= N-1且i> = 0)。