2021-05-16:時(shí)間復(fù)雜度必須是logN,如何求階乘從右向左第一個(gè)不為零的數(shù)?

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)=4
f(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é)果如下:


圖片
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容