2021-05-16:時(shí)間復(fù)雜度必須是logN,如何求階乘從右向左第一個(gè)不為零的數(shù)?
福大大 答案2021-05-16:
這道題logN的解法是大步小步法,網(wǎng)上非常難找。另外論代碼簡(jiǎn)潔度,明顯是我的代碼最簡(jiǎn)潔。你看了代碼后,你會(huì)非常失望。因?yàn)槟憧嗨稼は攵枷氩怀鰜?lái)的問(wèn)題,原來(lái)這么簡(jiǎn)單。
假設(shè)數(shù)字是N。
1.當(dāng)N能被5整除時(shí),采用大步法。N變成N/5。
1.1.當(dāng)N被4整除時(shí)。當(dāng)N=20時(shí),f(20)=f(4)。
1.2.當(dāng)N被4整除余1時(shí)。當(dāng)N=5時(shí),f(5)=2f(1)。
1.3.當(dāng)N被4整除余2時(shí)。當(dāng)N=10時(shí),f(10)=4f(2)。
1.4.當(dāng)N被4整除余3時(shí)。當(dāng)N=15時(shí),f(15)=8f(3)。
綜合上述4種情況。f(N)=【2的(N&3)次方】f(N/5)。
2.當(dāng)N不能被5整除時(shí),采用小步法。N變成N-1。當(dāng)N=27時(shí),f(27)=(27%10)f(26)=7f(26)。
代碼用golang編寫。代碼如下:
package main
import "fmt"
func main() {
for i := 1; i <= 3125; i++ {
fmt.Println(i, FactRightNotZero(i))
}
}
func FactRightNotZero(n int) int {
ans := 1
for n > 0 {
if n%5 == 0 {
ans <<= n & 3 //這是精髓
n /= 5
} else {
ans *= n % 10
n--
}
ans %= 10
}
return ans
}
執(zhí)行結(jié)果如下:
圖片