程式設計之美 不要被階乘嚇到

2021-06-28 12:10:01 字數 1505 閱讀 8263

題目

1、給定乙個整數n,那麼階乘n!末尾有多少個0呢?

2、求n!的二進位制表示中最低位1的位置?

先來看怎麼計算階乘,當然可以是迴圈,也可以是遞迴,上**:

public long factorial1(int n) 

return sum;

}public long factorial2(int n)

return n*factorial2(n-1);

}

兩種方法都比較簡單。但是很明顯如果本題也這樣計算的話,明顯long型會溢位,並且時間複雜度也比較高。那怎麼辦?

問題1解法一

n個自然數相乘,結尾0的個數,依賴有多少個10相乘,而多少個10則依賴與因子中2的個數和5的個數,而對於連續的自然數來說,2出現的頻率比5高的多,所以最終只需要計算出因子中5的個數,即為答案。

public int trailingzeroes1(int n) 

}return count;

}

當然你可以優化,把i的初始值設定為5,每次遞增也為5。但是還是不夠高效

解法二令f(x)表示正整數x末尾所含有的「0」的個數,則有: 

當0 < n < 5時,f(n!) = 0; 

當n >= 5時,f(n!) = k + f(k!), 其中 k = n / 5(取整)

資料功底比較好的可以去證明一下,我就不證明了,上**:

public int trailingzeroes2(int n)
就是這麼簡練。

解法三還是計算5的個數:

公式:z = [n/5] +[n/52] +[n/53] + …(不用擔心這會是乙個無窮的運算,因為總存在乙個k,使得5k > n,[n/5k]=0。)

公式中,[n/5]表示不大於n的數中5的倍數貢獻乙個5,[n/52]表示不大於n的數中52的倍數再貢獻乙個5,……**如下:

public int trailingzeroes3(int n) 

return count;

}

問題2

要求的是n!的二進位制表示中最低位1的位置。給定乙個整數n,求n!二進位制表示的最低位1在第幾位?例如:給定n = 3,n!= 6,那麼n!的二進位制表示(1 010)的最低位1在第二位。

為了得到更好的解法,首先要對題目進行一下轉化。

首先來看一下乙個二進位制數除以2的計算過程和結果是怎樣的。

把乙個二進位制數除以2,實際過程如下:

判斷最後乙個二進位制位是否為0,若為0,則將此二進位制數右移一位,即為商值(為什麼);反之,若為1,則說明這個二進位制數是奇數,無法被2整除(這又是為什麼)。

所以,這個問題實際上等同於求n!含有質因數2的個數。即答案等於n!含有質因數2的個數加1。

public int lowestone1(int n) 

return count;

}

階乘MySQL 程式設計之美 2 2不要被階乘嚇到

題目 1 給定乙個整數n,那麼n的階乘n!末尾有多少個0?例如n 10,n!3628800,末尾有兩個0.2 求n!的二進位制表示中最低位1的位置。問題一 題目解析 這道題如果直接求n!的話也可以,不過萬一溢位了怎麼辦?即使定義longlong型別的也不合適。那 題目 1 給定乙個整數n,那麼n的階...

不要被階乘嚇到

1.給定整數n,那麼n的階乘n 末尾有多少個0?這個問題經過質因子分解轉換為求5的指數 ret 0 for i 1 i n i n k 等於1,2,3.n中能被k整除的數的個數 證明 1,2,3.n中能被k整數的數為 k k 2 k 3 k 4 k n 其中 k 1 n n k n n 所以能被k整...

不要被階乘嚇到

程式設計之美有一道關於階乘的題目 1給定乙個整數n,那麼n的階乘等於n 末尾有多少個0呢,例如n 10,n 3628800,n 的末尾有兩個0 2求n 的二進位制表示中最低位為1的位置。階乘定義 n return ret 解法二 作者根據 n k 等於1,2,3 n中能被k整除的數的個數規律,得出下...