我偶然发现了这个解决方案,但我无法理解究竟发生了什么。有人可以解释一下!
根据我的理解,它试图通过计算一半细胞然后加倍来计算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))
答案 0 :(得分:1)
从某种意义上说,这是一种递归的分而治之算法。 1
左移位有效地将数字除以2
(丢弃任何余数)。 minProductHelper
使用smaller
将2
除以s = smaller >> 1
,然后返回递归导出的s * bigger
和(smaller - s) * bigger
之和。由于加法和乘法的属性,你有((smaller - s) * bigger) + (s * bigger) == smaller * bigger
这是你想要的结果。您有两个基本情况,即smaller
为0
或1
,因此您可以想象对minProduct(a,b)
的调用将继续a
或{ {1}}成为一半(并将那两半分成两半),直到所有必须做的是总结一堆涉及b
和一些数字或0
和一些数字的产品,这可能是无需使用1
运算符即可确定。较小的数字总是减少一半而不是较大的数字,因为这样可以通过较少的递归调用来达到基本情况。
答案 1 :(得分:0)
假设您将5和6相乘。然后程序首先计算出最小的数字,即5.然后通过将最小的数字除以两个完整的部分(几乎相等)来调用自身。
minProduct(5,6)=minProduct(2,5)+minProduct(3,6)
。然后将minProduct(2,6)
计算为minProduct(1,6)+minProduct(1,6)
。既然较小的数字是1,程序只返回6并且计算出值。这发生在每个函数调用中。
minProduct(5,6)
=minProduct(2,5)+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)。较少的函数调用意味着更快的算法。
为什么minProduct(0,a)有条件? 你确实看到了为什么有minProduct(1,a)的条件。但是minProduct(0,a)有一个条件,因为有一个特殊情况乘以2.当你调用minProduct(2,3)时。这解析为minProduct(2,3)和minProduct(0,3)。所以你需要单独处理它。