我想用标题传达的是以下练习: 给出一个正数和负数的列表,其中0 <0。 N&lt;从该列表中,需要找到最大子阵列总和,但它应该是某个阈值(x)下的最大总和。这个练习是用c ++解决的,但这并不重要。在给定时间约束的情况下,O(n ^ 2)的朴素方法也不够快。我也想不出一个简单的方法来使这个工作像最大子数组和。
例如: 清单:1 -4 5 6 -3 -2 14
如果阈值为4,则最佳解决方案为{-4}
如果阈值为9,则最佳解决方案为{-3 -2 14}
如果阈值为100,则最佳解决方案为{5 6 -3 -2 14}
如果阈值为7,则最佳解决方案为{-4 5 6}
如果阈值为2,则最佳解决方案为{-2}
对于我如何解决问题感兴趣的人:
我使用的O(n ^ 2)解决方案只是循环遍历每个可能的子数组和。它没有重新计算每一笔钱,而只是添加了一个新的数字。
答案 0 :(得分:1)
计算部分总和:P(i) = sum(a[0]...a[i])
对于给定位置对x,y(x <= y),总和为P(y) - P(x-1)
。
因此,如果我们修复y,那么您正在寻找大于或等于y的最小值 - 目标。
因此迭代集合并将项目插入到平衡树中(就像在大多数语言中设置一样)。然后你可以在集合中查找值并返回值(在C ++中,upper_bound几乎完全符合你的需要)。继续这样做,找到满足条件的最大组合。
查找,插入应为O(log N),因此整体解决方案将为O(N logN)。