优化算法的技巧

Posted

技术标签:

【中文标题】优化算法的技巧【英文标题】:Tips in optimizing an algorithm 【发布时间】:2014-04-01 03:29:12 【问题描述】:

我会尽量用措辞来表达这个问题,但不要让它听起来像是在寻找家庭作业的答案(这只是算法的练习题)

您有一个数字数组,其中每个值最多出现 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)

我可以采取哪些步骤来优化算法。 (或与此相关的任何算法)。显然,这个解决方案是第一个想到的,但我无法想象出更有效的更好解决方案。

编辑:为了这个问题,我只想说所有元素都是积极的

【问题讨论】:

【参考方案1】:

计算累积和数组:

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.所有的元素总是积极的吗?

【讨论】:

哇,这真是太聪明了!我真的希望我有这样的创造性解决方案的诀窍。在尝试优化我的解决方案时,您首先考虑的是什么? (试图提高我的优化技能) 如果您可以使用额外的内存,请查看 Pham Trung 关于 hashmap/dusctionary 的建议 @CoderNinja 从中缀聚合减少到前缀聚合是算法工程中众所周知的构造。学习这些东西只需要一点练习。如果您想练习算法/解决问题的技能,我可以推荐 TopCoder 或 Codeforces 等平台(但这需要付出努力,没有免费的午餐,也没有简单的技巧可以神奇地让您更快地解决问题)。 @CoderNinja 您可能会注意到,初始算法一次又一次地计算几乎相似的总和(在稍微偏移的间隔上)。【参考方案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];

还要注意数组中的每个值只有两次出现,我们可以使用映射/字典或数组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)

【讨论】:

预期 O(n) ;) 甚至可能是 O(n) 的概率很高,具体取决于哈希表的实现

以上是关于优化算法的技巧的主要内容,如果未能解决你的问题,请参考以下文章

图像分类算法优化技巧

MATLAB教程案例11~20总结优化类算法matlab仿真经验和技巧总结

编写高效的Java代码:常用的优化技巧

CNN调参目标检测算法优化技巧

剪枝算法--优化搜索(转载)

动态规划之空间优化与总结回顾