省示范院校建設(shè)網(wǎng)站seo入門教程網(wǎng)盤
目錄
一.快速冪
1.問題的引入
2.快速冪的介紹
3.核心思想
4.代碼實現(xiàn)
?2.猴子碰撞的方法數(shù)
1.題目描述
2.問題分析
3.代碼實現(xiàn)
一.快速冪
1.問題的引入
問題:求解num的n次冪,結(jié)果需要求余
+7
對于這個問題我們可能就是直接調(diào)用函數(shù)pow(a,b)來直接求解a的b次冪問題,但是如果求解的結(jié)果很大,超過的double的數(shù)值范圍,我們要求對最終的結(jié)果求余+7,我們?nèi)绻苯诱{(diào)用pow()函數(shù)的話,求解出來的數(shù)已經(jīng)超出了double的最大范圍,根本無法求出,這個時候我們是否可以考慮在求解的過程中每一次的結(jié)果都求余
+7,而不是只在最終的結(jié)果求余
+7這樣最終的結(jié)果肯定是小于
+7,一定不會超出最大的范圍.
2.快速冪的介紹
快速冪:快速冪就是快速算底數(shù)的n次冪。其時間復(fù)雜度為 O(log?N),與樸素的O(N)相比效率有了極大的提高。
3.核心思想
例如計算,10的二進(jìn)制為1010,相當(dāng)于求解
次方
=3*3*3*3*3*3*3*3*3*3
=(3*3)*(3*3*3*3*3*3*3*3)
=*
相當(dāng)于我們每次對10的二進(jìn)制的每一個位置求權(quán)(如果是二進(jìn)制這個位是1),則乘以當(dāng)前的疊加的數(shù),
例如進(jìn)行求余的步驟 :
定義變量ans保存的結(jié)果?? 1010位10的二進(jìn)制表達(dá)方式
1010的第一位為0,這個時候num=num*num=;??? 二進(jìn)制形式為:
1010的第二位為0,這個時候求權(quán)為1,ans=ans*num=? num=num*num=
;二進(jìn)制形式為:
1010的第三位為0,這個時候num=num*num=; 二進(jìn)制形式為:
1010的第四位為1,這個時候求權(quán)為1,ans=ans*num=*
? num=num*num=
;
4.代碼實現(xiàn)
1.求余+7的版本,返回數(shù)據(jù)類型為int的結(jié)果
public int quickPow(long num,int n){long ans=1;long mod=1000000007;while(n!=0){if((n&1)==1)ans=(ans*num)%mod;num = num * num % mod;n>>=1;}return (int)(ans%mod);}
?2.不求余的版本,返回數(shù)據(jù)類型為long的結(jié)果
public long quickPow(long num,int n){long ans=1;while(n!=0){if((n&1)==1)ans=ans*num;num = num * num;n>>=1;}return ans;}
?2.猴子碰撞的方法數(shù)
1.題目描述
現(xiàn)在有一個正凸多邊形,其上共有
n
個頂點。頂點按順時針方向從0
到n - 1
依次編號。每個頂點上 正好有一只猴子 。下圖中是一個 6 個頂點的凸多邊形。
?
每個猴子同時移動到相鄰的頂點。頂點
i
的相鄰頂點可以是:
- 順時針方向的頂點
(i + 1) % n
,或- 逆時針方向的頂點
(i - 1 + n) % n
。如果移動后至少有兩個猴子位于同一頂點,則會發(fā)生 碰撞 。
返回猴子至少發(fā)生 一次碰撞 的移動方法數(shù)。由于答案可能非常大,請返回對
109+7
取余后的結(jié)果。注意,每只猴子只能移動一次。
力扣: 力扣
2.問題分析
正難則反,題目問的是至少發(fā)生一次碰撞的移動次數(shù),我們不妨把問題轉(zhuǎn)換為求解猴子一次都不碰撞的次數(shù),猴子一共有2的n次冪中跳躍的方式,求中有兩種是一次都不碰撞的,一種是猴子全部順時針進(jìn)行跳躍,一種是猴子逆時針進(jìn)行跳躍,所以猴子至少發(fā)生一次碰撞的次數(shù)=猴子總共的移動次數(shù)-2
3.代碼實現(xiàn)
public int monkeyMove(int n) {long ans=1,a=2;long mod=1000000007;while(n!=0){if((n&1)==1)ans=(ans*a)%mod;a = a * a % mod;n>>=1;}return (int)((ans+mod-2)%mod);}
?
?