172. 階乘後的零— —力扣每日一題
阿新 • • 發佈:2022-03-28
172. 階乘後的零— —2022/3/25
1、題目
給定一個整數 n
,返回 n!
結果中尾隨零的數量。
提示 n! = n * (n - 1) * (n - 2) * ... * 3 * 2 * 1
2、示例
1)示例1
輸入:n = 3
輸出:0
解釋:3! = 6 ,不含尾隨 0
2)示例2
輸入:n = 5
輸出:1
解釋:5! = 120 ,有一個尾隨 0
3)示例3
輸入:n = 0
輸出:0
3、解答
3.1 思路及具體操作
- 初步的思路還是計算出階乘之後的數,來計算0的個數
- 由於
java
給出的基本資料型別最大的長度也僅僅很小,所以不能直接使用基本資料型別去做 - 這裡想的初步思路是使用
陣列+字串
- 計算的值也是使用陣列去儲存
-
trailingZeroes(int n)
計算0的個數 -
transform(int n)
將整數轉換成整型陣列 -
factorial(int n)
計算n!
的值 -
factorials(int[] m,int[] n)
計算m
與n
的乘積
-
3.2 程式碼
/*本方法採用陣列儲存階乘的資料,然後根據陣列判斷0的個數 * 雖然解決了辦法,但是超出了時間限制,很難受 * */ public class Solution { public static void main(String[] args) { int[] arr = factorial(100); for (int i = 0; i < arr.length; i++) { System.out.print(arr[i]); } System.out.println("\n"+arr.length); System.out.println(trailingZeroes(100)); } //判斷n階乘0的個數 public static int trailingZeroes(int n) { if(n == 0){ return 0; } int m = 0; int[] intArr = factorial(n); for (int i = intArr.length -1; i >= 0; i--) { if(intArr[i] == 0){ m++; }else{ break; } } return m; } //整型轉換成陣列 public static int[] transform(int n){ String ms = "" + n + ""; char[] msc = ms.toCharArray(); int[] intArr = new int[msc.length]; for (int i = 0; i < msc.length; i++) { intArr[i] = (int) msc[i] - 48; } return intArr; } //用陣列儲存階乘的資料 public static int[] factorial(int n){ int nums = n; int[] result = new int[n]; int num = n; for (int i = 0; i < nums; i++) { if(i==0){ result = factorials(transform(num),transform(num-1)); num --; }else{ if(num == 1){ break; } num --; result = factorials(result,transform(num)); } } int a = 0; int b = 0; for (int i = 0; i < result.length; i++) { if(result[i] != 0){ a = result.length - i; b = i; break; } } int[] results = new int[a]; for (int i = 0; i < a; i++) { results[i] = result[b+i]; } return results; } //返回兩個數相乘的結果,返回結果為陣列 public static int[] factorials(int[] m,int[] n) { int result[] = new int[m.length+n.length]; for(int i = 0; i < m.length; i++){ for(int j = 0; j < n.length; j++){ result[result.length-1-i - j] += (m[m.length-1-i] * n[n.length-1-j])%10; result[result.length-i - j - 2] += (m[m.length-1-i] * n[n.length-1-j])/10; } } return result; } }
3.3 思考
- 其實計算出階乘的值這個方法是由於想要再練習一下階乘的計算,所以採用的直接法做
- 但是本題的實質其實是計算尾部 0 的個數,因此只需要明白什麼樣的值才能使得尾部可以為0
4、優化解法
4.1 優化思路
- 尾部 0 的產生是由於 10 的出現,所以只需要判斷乘數中會出現的 10 的個數就可以判斷出尾部 0 的個數
- 那我們就需要知道 10 可以是 5 與 2 的乘積,所以可以採用判斷 5 的個數(所有5的公倍數相當於
5*公倍數
個5) - 因為5在2之後,所以不需要考慮 2 的個數問題
4.2 程式碼
public static int trailingZeroes(int n) { int num = 0; for (int i = 5; i <= n; i+=5) { for (int x = i; x % 5 == 0; x /= 5) { num++; } } return num; }