我试着说出这个问题而不会让我觉得我正在寻找作业答案(这只是算法的实践问题)
你有一个数字数组,每个值最多可以出现2x [1 3 5 2 5 1 2 3] 检查从一个值到另一个自身实例的总和(5 + 2 + 5)(2 + 5 + 1 + 2)
找到找到这种总和的最大值的算法。
我提出了一个非常简单的算法:
iterate through the array (for i=1 to n)
iterate through the remaining array (for j=i+1)
if A[i] == A[j]
s = 0
iterate through the values between those two points (for k=i to j)
s = s + A[k]
maxVal = max(maxVal,s)
我可以采取哪些步骤来优化算法。 (或任何算法)。显然,这个解决方案是我想到的第一个解决方案,但是我无法想象更好的解决方案。
编辑:为了解决这个问题,我只会说所有元素都是正版
答案 0 :(得分:3)
计算累积总和数组:
C[0] = A[0]
for i = 1 to n
C[i] = C[i - 1] + A[i]
A[1 3 5 2 5 1 2 3]
C[0 1 4 9 11 16 17 19 22]
找到对时使用这些值:
Sum(i to j) = C[j] - C[i - 1]
P.S。所有元素都是正面的吗?
答案 1 :(得分:2)
通过预先计算从索引1到索引i的所有总和并将其存储到数组中,调用sum
,可以摆脱最内部的循环。因此,如果你想得到i和j之间的和,结果将是sum [j] - sum [i - 1]。
for(i = 1 to n)
sum[i] = A[i];
if(i - 1 > 1)
sum[i] += sum[i - 1];
另请注意,数组中每个值只出现两次,我们可以使用map / dictionary或数组pos
(如果可能)记住此值的第一个位置,如果我们再次看到它,我们可以用它来计算第一个和这个位置之间的总和。
pos[];
for(i = 1 to n)
if(pos[A[i]] ==0)
pos[A[i]] = i;
else
result = max(result,sum[i] - sum[pos[A[i]] - 1])
总的来说,这个时间复杂度将是O(n)