时间复杂度必须是logN,如何求阶乘从右向左第一个不为零的数?
这道题logN的解法是大步小步法,网上非常难找。另外论代码简洁度,明显是我的代码最简洁。你看了代码后,你会非常失望。因为你苦思冥想都想不出来的问题,原来这么简单。
假设数字是N。 1.当N能被5整除时,采用大步法。N变成N/5。 1.1.当N被4整除时。当N=20时,f(20)=f(4)。 1.2.当N被4整除余1时。当N=5时,f(5)=2f(1)。 1.3.当N被4整除余2时。当N=10时,f(10)=4f(2)。 1.4.当N被4整除余3时。当N=15时,f(15)=8*f(3)。 综合上述4种情况。f(N)=【2的(N&3)次方】*f(N/5)。 2.当N不能被5整除时,采用小步法。N变成N-1。当N=27时,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
}
执行结果如下: