快速冪
個人博客:https://sgeekioi.github.io/2019/07/31/fastpower/#more
【介紹】
顧名思義,快速冪就是快速算底數的n次冪。其時間複雜度爲 O(log₂N), 與樸素的O(N)相比效率有了極大的提高。
【描述】
計算a的n次方就是將n個a乘起來。但是,當n的值特別大的時候,這種累乘的方法就不合適了。不過,由結合律我們知道。二進制取冪的想法是,我們將取冪的任務按照指數的二進制表示來分割成更小的任務。我們來舉個例子
11的二進制數爲 1011。 對進制不太理解的戳這裏
KaTeX parse error: No such environment: equation at position 7: \begin{̲e̲q̲u̲a̲t̲i̲o̲n̲}̲ 3^{11} = 3^{10…
上面這個算式是怎麼來的呢。看下面
KaTeX parse error: No such environment: equation at position 7: \begin{̲e̲q̲u̲a̲t̲i̲o̲n̲}̲ 3^1 = {3^2}^0 …
也就是爲了計算,我們只需要將二進制位對應爲1的整係數冪乘起來就行了:
KaTeX parse error: No such environment: equation at position 7: \begin{̲e̲q̲u̲a̲t̲i̲o̲n̲}̲ 3^{11} = 3 \ti…
將上述過程說的形式化一些,如果把n寫作二進制爲,那麼有:
KaTeX parse error: No such environment: equation at position 7: \begin{̲e̲q̲u̲a̲t̲i̲o̲n̲}̲
n=n_t2^t+n_{t-…
其中 。那麼就有
KaTeX parse error: No such environment: equation at position 7: \begin{̲e̲q̲u̲a̲t̲i̲o̲n̲}̲ a^n=(a^{n_t2^t…
根據上式我們發現,原問題被我轉換成了形式相同的子問題的乘積,並且我們可以在常數時間內從項推出項。這個算法的複雜度是的。
##【代碼實現】
遞歸方法
public double power1(double a, int n) {
if (n == 0) {
return 1;
}
double res = power(a,n/2);
if((n%2)==1){
return res * res * a;
}else{
return res * res;
}
}
非遞歸式
它在循環的過程將二進制爲1時對應的冪累乘到答案中。儘管兩者的理論複雜度相同,但第二種在實踐過程中的速度會比遞歸式更快的,因爲遞歸會重複運算花費一定開銷。
public double power2(double a,int n){
double res = 1;
while (n>0){
if((n&1)==1){
res*=a;
}
a*=a;
n>>=1;
}
return res;
}