【问题标题】:Project Euler #8: Is there a more efficient algorithm than brute force calculation?Project Euler #8:有没有比蛮力计算更有效的算法?
【发布时间】:2012-10-08 18:59:29
【问题描述】:

问题

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

我计算了所有可能的产品并选择了最大的一个——蛮力算法。

有没有更高效的算法?或者是暴力破解的唯一方法。

旁注

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

【问题讨论】:

  • +1 感谢您的精彩回答!

标签: algorithm


【解决方案1】:

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

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

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

【讨论】:

  • 请注意不要除以 0 :)。
  • @IVlad:我把这些细节留给了 OP :)
【解决方案2】:

由于问题要求连续数字,在这种情况下,'brute force' 表示 O(n)n 是位数(1000)。只要号码中没有某种模式,您将需要 n 个步骤来扫描号码,因此这是最快的解决方案。

你可以缓存最后4位的乘积或做类似的把戏,但你肯定不会比O(n)更好。

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        猜你喜欢
        • 2015-07-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-11
        • 1970-01-01
        • 2019-08-13
        • 2015-06-22
        相关资源
        最近更新 更多