项目欧拉#8:有比蛮力计算更有效的算法吗?

时间:2012-10-08 18:59:29

标签: algorithm

问题

有没有比蛮力方法更好的方法来找到Project Euler问题8的解决方案,即Find the greatest product of five consecutive digits in the 1000-digit number

我计算了所有可能的产品并选择了最好的产品 - 蛮力算法。

是否有更高效的算法?或者是蛮力方法是唯一的方法。

旁注

  • 这不是一个家庭作业问题。
  • 我不是要求问题8的结果。

4 个答案:

答案 0 :(得分:7)

您可以使用大小为5的滑动窗口并在O(d)中解决此问题,其中d是输入数字中的位数。

您可以通过窗口中起始编号的索引来表示窗口,窗口i的值是索引为[i,i + 4]的元素的乘积。现在,在每次迭代中,您将窗口向右滑动,有效地删除最左边的元素并向右添加新元素,窗口的新值为old_value / left_most_ele * new_right_ele。继续为范围i中的每个索引[0,d-5]执行此操作,并找到最大窗口值。

请注意,内部循环运行五次的嵌套循环的强力方法也是O(d)解决方案。但是上面的方法稍好一些,因为我们不是在每一步中进行五次乘法,而是进行一次乘法和一次除法。

答案 1 :(得分:6)

由于问题要求连续数字,“暴力”在这种情况下意味着 O(n) n 是数字数字(1000)。只要数字中没有某种模式,只需扫描数字就需要 n 步骤,因此这是最快的解决方案。

您可以缓存最后4位数的产品或做类似的技巧,但绝对不会比 O(n)更好。

答案 2 :(得分:5)

是和否。您必须查看五个连续数字的每个序列,但不必每次都通过循环将每个序列相乘。您可以使用快捷方式来加快处理速度。例如,如果下一个数字为0,则可以向前跳过。此外,如果下一个数字小于从序列中删除的最后一个数字,则您知道与其他四个常用数字相乘的结果将更小,因此跳过相乘并转到下一个数字。当你只有1000个数字时,这样的技巧不会产生太大的影响,但后来的问题会相同,只是输入较大。

答案 3 :(得分:2)

一个优化是计算前五位数的乘积,并在每次迭代中乘以下一位数并除以前一位(移动窗口)。

另一个优化是立即丢弃0周围的所有数字。