总和大于给定值的最小子阵列的大小

时间:2014-06-17 18:16:20

标签: algorithm arrays

最初的问题是

总和大于给定值的最小子阵列 给定一个整数数组和一个数字x,找到总和大于给定值的最小子数组。在http://www.geeksforgeeks.org/minimum-length-subarray-sum-greater-given-value/

但如果问题只是找到最小的子阵列的大小,我们可以使用分而治之的方法吗?

算法: Size_of_min_subarray(1,n)=

min of Size_of_min_subarray(1,n / 2),Size_of_min_subarray(n / 2,n),Size_of_array_containing mid_element(s)}

Size_of_array_containing_mid_element由:

计算

取中间元素,初始化sum = mid元素/ mid元素之和和num_elements = 1/2基于n是奇数或偶数。如果sum <=给定值,检查数字是否向右或向左更大。将更大的元素添加到总和和增量num_elements。重复直到总和>给定的价值。

插图:

1,4,45,6,0,19,阈值= 51

min_size = min {min_size {1,4,45},min_size {6,0,19},min_containing_45and6}

min_containing_45and6:

sum = mid元素/ mid元素之和= 45 + 6 = 51&lt; = 51,num_elements = 2。由于4> 0将4加到sum,sum = 55并且增加num_elements。 num_elements = 3。

min_size = min {不可能,不可能,3} = 3。

这个算法是否正确?我认为如果O(logn),它的复杂性是正确的吗?

编辑:我意识到我用来查找Size_of_array_containin_mid_elemnts的算法是错误的。任何人都建议使用算法来找到这个值吗?

3 个答案:

答案 0 :(得分:2)

  1. 没有子线性算法可以解决这个问题,因为它必须至少考虑一次每个数组元素(最坏的情况)。

  2. 您的算法缺少“基础”步骤,即小Size_of_min_subarray(1,n)的{​​{1}}(无论“小”是什么)。

  3. 您算法的重现次数为n,其中F(n)=2*F(n/2)+G(n)F(n)的复杂度Size_of_min_subarraynG(n)的复杂性{1}}。自Size_of_array_containing_mid_element(n)起,您的算法为G(n)~O(n)

答案 1 :(得分:0)

  1. 如果您只是想在没有任何其他参数的情况下找到最小的子数组(如果我正确读取它),那么它是不是总是大小为1的数组?

  2. 我接近这个方法(可能是更快的方法)就是在原始数组中有2个“指针”到索引。在循环中将一个“指针”移动到数组中,直到从后面“指针”到前面“指针”的值之和大于值x。您可以相当容易地存储该子数组或长度,具体取决于您要对信息执行的操作。一旦找到可行的解决方案,就可以向后移动“指针”,直到两个“指针”之间的总和小于阈值。一旦发生这种情况,您再次向前移动前“指针”并重复上述步骤。您比较子阵列的长度,并最终得出正确的答案。运行时为O(n ^ 2),但它得到了正确的答案。

  3. 我能看到的唯一问题是,有可能错过一些案例。例如,如果您有{45,1,0,4,6,19}(阈值仍为51),我认为通过按照您的方式拆分数组/列表,您可能会因为拆分而错过解决方案和6个在列表的不同部分。

    如果我错了,请纠正我,但我认为我所拥有的是接近的。

答案 2 :(得分:0)

一个非常简单的算法是获得每个可能的子数组大小的最大值,直到你有一个总和大于给定值的子数组。

因此,如果您有一个包含6个元素的数组,则可以开始检查是否存在大于或等于给定值的子数组(换句话说,单个值大于给定值)。如果不检查大小为2的子数组。如果没有检查大小为3的子数组,它继续...

最糟糕的情况是,您需要将所有数组值相加以达到给定值。