问题
有没有比蛮力方法更好的方法来找到Project Euler问题8的解决方案,即Find the greatest product of five consecutive digits in the 1000-digit number。
我计算了所有可能的产品并选择了最好的产品 - 蛮力算法。
是否有更高效的算法?或者是蛮力方法是唯一的方法。
旁注
答案 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
周围的所有数字。