Arrays 如何求最大长度子序列的最大和

Arrays 如何求最大长度子序列的最大和,arrays,algorithm,Arrays,Algorithm,我正在做一个面试问题,我找不到任何教科书上的答案。给定一个整数列表,查找不超过给定K长度的任何连续值/子列表的最大和 这里是一个提纲。你有X[i,其中i=1..N]个数字。给定K,假设K,它看起来类似于最大子阵问题。提及_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 = func

我正在做一个面试问题,我找不到任何教科书上的答案。给定一个整数列表,查找不超过给定K长度的任何连续值/子列表的最大和

这里是一个提纲。你有X[i,其中i=1..N]个数字。给定K,假设K,它看起来类似于最大子阵问题。提及_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);
var arr=[1,2,31,24,34,3,23,24,3,25,34,54,3,2,34];
var getSmallestSubSeqSum=函数(arr,k){
var totalLength=arr.length,指数=0,总和=[];
对于(索引=0;索引

上面的代码片段应该有助于这是javascript。

N个数字是X[0],…X[N-1],假设1设p[i]为前缀和a[0]+…+a[i-1]。我们可以很容易地在线性时间内计算序列p。对于固定索引i,大小不超过K且右边界位于索引i处的子阵列的最大和可计算为

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)中的最小项。这正是问题所在,使用特殊的队列数据结构有一个很好的解决方案。该队列支持推送/弹出操作以及摊销O(1)中的最小值。使用它,我们的算法如下所示:

q=new MinQueue()
总和=0
答案=0
对于i:=0到N-1:
q、 push(sum)#sum==p[i]
如果len(q)>K:
q、 流行音乐()
总和+=a[i]
答案=max(答案,和-q.min())#和=p[i+1]

总运行时间是线性的。

到目前为止,您是否尝试过任何方法来解决您的问题?先表现出你的努力,这样人们才能表现出他们的努力。请先阅读并居中。@idstam我尝试过二次解的两种变体,但我希望找到线性时间解。实际上,该解可能是比KE.g更小的子数组。K=2,a=[-1,-1,1,-1]的确,但我的理解是,K必须被观察到…继续..否则(这是一个非常有趣的问题,谢谢),概括你在两端寻找负数的过程--两端产生-ve和的最大子序列可以被丢弃并重复处理(对于每个子序列)直到没有更多的丢弃(想知道一次丢弃是否足够——有什么想法吗?)引用:“不超过给定的K”你描述的贪婪方法显然是正确的,但它不会产生一个快速算法,即ω(NK),然而,尽管线性时间是可能的,这在计算和[索引]时效率相当低。请在bottomHi@Niklas上查看我的答案,我已经在这里实现了您的解决方案:,即使队列没有O(1)
min
。预期的答案是9,为什么是10?我有什么地方出错了吗?@paranoid android你正在用右边弹出的deque上的
pop()
。您应该改用
popleft()
。FWIW,这是一个用C++实现的最小队列:这是非常有用的,非常感谢。但是,目前还没有发现列表中的所有值都是负数的情况。@paranoid android为什么不呢?在这种情况下,答案应该是0否?如果不是,只需将答案初始化为否定即可infinity@paranoid-这当然是一个定义问题。在这种情况下,我认为空子数组是最优的,和0。