示例:
给出随机数列表[1,5,1,1,3,10,5,4,2,1]
,测试元素N=10 at index 5
和MIN=20
。
包含10
且total>20
的最短子列表显然是[3,10,5,4]
列表total=22
和size=4
。
问题:
以有效的方式找到这样一个子列表的算法是什么?
编辑:
可能存在满足“最短”条件的不同子列表。 [10,5,4,2]
与[3,10,5,4]
一样短,也是有效的结果。
此问题中的“子列表”是原始列表的连续项目块。 [5,10,5,4]
不是有效的子列表(我将其称为子集)。
答案 0 :(得分:1)
以下算法应为O(n):
从test元素开始,向左添加元素,直到sum> = min。这给出了子列表长度l的第一个猜测(从索引i开始)。没有增加长度l的子列表的起始索引i,每个步骤(直到到达您的测试元素)并且每个步骤测试是否可以将子列表缩短一个(在右边,即减小长度l)而不会小于min。
照顾边缘情况:左边的总和不够大或总和不够大。
答案 1 :(得分:0)
找到最短的子列表> MAX与查找最短子列表< = MAX相同,如果添加了之前或之后的项目,则子列表的总数超过MAX:[1,5,1,1,3,10,5,4,2,1]
和MAX=20
,[1,3,10]
为包含10
但无效的子列表,因为添加下一个5
会产生总计19 < MAX
。第一个有效的子列表位于[5,1,1,3,10]
。
算法:
marker
。left
和right
。N
。left
移至左侧while total(at left, ..., at N) <= MAX
或left = 0
。
left > 0
将n - left + 1
存储在marker
中。转到6。right
移至右侧while total(at left, ..., at right) <= MAX
或right = list.size - 1
。
right < list.size - 1
将right - left + 1
存储在marker
。list.size
。while left < N and right < list.size - 1
:
left
向右移动一个。at right + 1
(如果有)。
total + at right + 1 > MAX
将right - left + 1
存储在marker
。无论如何,我会给霍华德答案。