【问题标题】:Minimum across cumulative sums with different starting indices具有不同起始索引的累积总和的最小值
【发布时间】:2013-09-01 00:40:27
【问题描述】:

问题:给定一个向量,我想知道一系列累积和的最小值,其中每个累积和是针对向量的递增起始索引和固定结束索引(1 :5, 2:5, ..., 5:5)。具体来说,我想知道是否可以使用for() 循环来计算这是否可以计算,以及该算法/计算是否有潜在的术语。我在 R 工作。

上下文:感兴趣的向量包含压力变化的时间序列。我想知道在一系列起点但终点固定的压力的最大(或最小)净变化。

详情+示例:

#Example R code    
diffP <- c(0, -1,  0,  1,  0,  0,  1,  0,  0,  0,  0,  0, -1,  0,  0,  0,  0,  0,  0,  0, -1,  0,  0)
minNet1 <- min(cumsum(diffP))
minNet1 #over the whole vector, the "biggest net drop" (largest magnitude with negative sign) is -1.
#However, if I started a cumulative sum in the second half of diffP, I would get a net pressure change of -2.
hold <- list()
nDiff <- length(diffP)
for(j in 1:nDiff){
   hold[[j]] <- cumsum(diffP[j:nDiff])
}
answer <- min(unlist(hold)) #this gives the answer that I ultimately want

希望我上面的例子有助于阐明我的问题。 answer 包含正确答案,但我宁愿在 R 中没有 for() 循环的情况下执行此操作。是否有更好的方法来进行此计算,或者我可以为其命名?

【问题讨论】:

    标签: r algorithm time-series cumulative-sum


    【解决方案1】:

    这被称为http://en.wikipedia.org/wiki/Maximum_subarray_problem,是一个典型的面试问题!

    大多数人——包括我——会使用 O(n^2) 算法解决它,但实际上有一个更好的算法,复杂度为 O(n)。这是上面链接中 Kadane 算法的 R 实现:

    max_subarray <- function(A) {
       max_ending_here <- 0
       max_so_far <- 0
       for (x in A) {
          max_ending_here <- max(0, max_ending_here + x)
          max_so_far <- max(max_so_far, max_ending_here)
       }
       max_so_far
    }
    

    由于在您的情况下,您正在寻找 minimum 子数组总和,因此您必须这样称呼它:

    -max_subarray(-diffP)
    [1] -2
    

    (或者你也可以重写上面的函数,将max替换为min。)

    请注意,是的,实现仍然使用for循环,但是算法的复杂度为O(n)(意味着操作数与length(diff)的顺序相同),应该是快的。此外,它不会消耗任何内存,因为它只存储和更新几个变量。

    【讨论】:

    • Hmmmm...“典型的面试问题”是哪个大型软件公司的?
    猜你喜欢
    • 2021-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-23
    • 2014-11-20
    • 1970-01-01
    • 2022-12-31
    • 1970-01-01
    相关资源
    最近更新 更多