最近看到一个简单的问题,原本题目是简化一个乘法运算,使用到了分治的思想,题目是这样的,假设x和y是两个长度为n的二进制数,我们的目标时计算x和y的乘积。如果直接暴力做乘法时间复杂度为O(n^2),而我们使用分治的方法,可以把x和y分为左、右两半,每一半为n/2位长。例如两个八位二进制数相乘,我们可以分x为xL,xR,yL,yR。那么x*y = (2^(n/2) xL + xR) * (2^(n/2) yL + yR) = 2^n xL * yL + 2^(n/2) (xL * yR + xR * yL) + xR * yR。这样需要做4个乘法(2的n次方直接用移位操作,所以不算乘法计算),不过每个乘法运算的复杂度却只有n/2,那么就是4 * (n/2 * n/2) = n^2,貌似复杂度完全没有减少啊!对,不过聪明的德国数学家高斯很早就发现,虽然两个乘法初看上去涉及4次实数乘法运算,但实际上却可以化简为3次实数乘法,你知道吗?自己试一下再看后面的答案哦~~

 

 

 

 

 

 

 

 

这个方法是德国数学家高斯发现的,他很早就发现虽然两个复数的乘法初看上去涉及4次实数乘法运算,但实际可以化简为3次实数乘法运算,我们先来看看高斯的发现,然后你就应该会明白上式如何化简为3次乘法了。

设两个复数a + bi,c + di。我们先来看三个辅助的量t1 = (a - b) * (c + d),t2 = a * d,t3 = b * c。两个复数相乘的结果实部为a * c – b * d,虚部为a * d + b * c。而实部可以表示为t1 – t2 + t3,虚部可以表示为t2 + t3。这样就可以用三次乘法完成复数相乘了。其思想是用加减代替了乘法。

好了让我们再看看上面的4次乘法,如法炮制:f1 = 2^(n/2)(xL + xR) * (yL + yR),f2 = xL * yL,f3 = xR * yR。

则x * y = f1 – 2^(n/2) f2 + f2 - 2^(n/2) f3 + f3。

这样我们就只做了3次规模为n/2的乘法,即3/4*n^2,这样的结果还比较满意,也许你觉得这样的优化微不足道,但我们可以一直这么分下去,最后得到递推表达式:T(N) = 3T(n/2) + O(n)。当n趋于无穷大时你会发现时间复杂度降到了O(n^lg3),这已经非常可观了,高斯果然牛X。