最后k个数字的总和与前k个数字的总和相同

时间:2013-06-06 10:59:03

标签: algorithm

我想找出给定范围内几个数字的前k个数字的总和是否等于最后k个数字的总和。这里的范围非常大,k小于20。

我们可以通过强力方法实现这一目标。有人可以建议一些其他有效的算法。同样的?

5 个答案:

答案 0 :(得分:1)

如果是一个范围,第一个数字不会经常改变,最后一个数字会以简单的方式改变。 S是前20位的总和。虽然secund数字不会改变,但当你转到下一个数字时,总和将增加1。因此,除了最后一个数字之外的所有数字都是固定的,如果最后一个数字等于i的总和是Si,那么唯一好的最后一个数字是n = S - Si + i。然后,您必须检查n是否介于0和9之间,以及结果数是否在区间内。这减少了十次查找次数。

您可以检查下一个较低的数字 如果第一个n小于0,则需要将secund数字减少-n。拨打n2这个secund数字。如果n2> = 0,好的数字将以(n2,0),(n2 -1,1),...,(0,n2)结束。这使复杂性降低了100。 如果n大于10,则将第二个数字增加n-9。将n2称为第二位数字。如果n2 <= 9,则好的数字是(n2,9),(n2-1,8),......,(0,某事物)。 这也使复杂性降低了100。

您可以对第三个数字执行相同操作,然后对第四个数字执行相同操作,直到20个。这将导致仅1个总和,以及O(解决方案数量)的复杂性,因此它是最小的。对于编码,请注意您的第一个数字可能会发生变化。每组20个第一个数字进行一次计算。

答案 1 :(得分:0)

对蛮力方法的一个理论上的改进:

1)总结第k个数字,存储在sumFirst中 2)总结最后的k个数字,但如果总和超过sumFirst则停止。

第2点可以节省一些最后几位的数字。

但你必须衡量额外的逻辑,花费更多,然后简单地添加所有k个数字。

答案 2 :(得分:0)

对蛮力的另一个改进:

i = 0, T = 0
while |T| < 9 * (k - i) 
  T = T + last[i] - first[i]
  i = i + 1
return T == 0 

答案 3 :(得分:0)

优化N-k

改进算法的一种方法是,当具有N位数的数字具有以下属性时:
N < 2k

例如,如果N = 5且k = 3,5 < 2x3,则数字为

abcde

您只需要abde进行计数(即无需检查k(3)位,因为3 rd 由k共享-last和k-first digits。)换句话说,双方计数的位数仅为

min(k, N-k), having N >= k

答案 4 :(得分:0)

如果要对同一个数组多次使用,可以将所有元素与前面的元素相加,O(n)数组的大小为n,即

for(int i = 1; i < n; i++)
     arr[i] = arr[i] + arr[i-1];

这会将您的数组从probability density function转换为cumulative distribution function(对于离散数字)。因此,您的查询将是O(1),即

if(arr[k-1] == (arr[n-1]-arr[n-k])) //arr[k-1] is sum of first k element
    return true;
return false;