我偶然发现了这个解决方案,但我无法理解这到底发生了什么。有人可以解释一下吗!
据我了解,它试图通过计算一半的单元格然后将其加倍来计算 a*b 网格中的单元格数量。但是我无法理解递归调用。
请不要提出其他解决方案,请尝试解释此解决方案:)
def minProduct(a,b):
bigger = b if a < b else a #a < b ? b : a
smaller = a if a < b else b #a < b ? a : b
return minProductHelper(smaller,bigger)
def minProductHelper(smaller, bigger):
if smaller == 0:
return 0
elif smaller == 1:
return bigger
# Compute half. If uneven, compute other half. If even, double it
s = smaller >> 1 # divide by 2
side1 = minProduct(s,bigger)
side2 = side1
if smaller % 2 == 1:
side2 = minProductHelper(smaller - s, bigger)
return side1 + side2
print(minProduct(5,6))
从某种意义上说,这是一种递归分而治之的算法。位左移1
有效地将数字除以2
(丢弃任何余数)。minProductHelper
使用s = smaller >> 1
将smaller
除以2
,然后返回递归派生的s * bigger
和(smaller - s) * bigger
之和。由于加法和乘法的性质,你得到了你想要的结果((smaller - s) * bigger) + (s * bigger) == smaller * bigger
。你有两个基本情况,即当smaller
0
或1
时,所以你可以想象对minProduct(a,b)
的调用会不断将a
或b
切成两半(以及这些半切成两半等),直到它所要做的就是将一堆涉及0
和一些数字或1
和一些数字的产品相加, 无需使用*
运算符即可确定。较小的数字总是减少一半,而不是较大的数字,因为这允许使用较少的递归调用达到基本情况。
假设您将 5 和 6 相乘。然后程序首先计算出最小的数字,即 5。然后,它通过将最小的数字分成两个完整的部分(几乎相等)来调用自己。
minProduct(5,6)=minProduct(2,6)+minProduct(3,6)
.然后minProduct(2,6)
以类似的方式计算成minProduct(1,6)+minProduct(1,6)
。现在较小的数字是 1,程序只需返回 6 并计算回值。每个函数调用都会发生这种情况。
minProduct(5,6) =minProduct(2,6)+minProduct(3,6) =minProduct(1,6)+minProduct(1,6)+minProduct(3,6) (Let minProduct(3,6)=18) for cohesion) =6+6+18 =30
为什么要先找出最小的数字?前面的答案准确地处理了为什么使用较小的数字而不是较大的数字。取两个任意数字 2 和 1000。我需要弄清楚 2*1000 是什么。更容易计算出 1000+1000 然后 (2+2+.+2).更少的函数调用意味着更快的算法。
为什么有最小产品(0,a)的条件?你确实明白为什么有minProduct(1,a)的条件。但是 minProduct(0,a) 有一个条件,因为有一个乘以 2 的特殊情况。当您调用 minProduct(2,3) 时。这将解析为 minProduct(2,3) 和 minProduct(0,3)。所以你需要单独处理这个问题。