不要被階乘嚇倒

階乘是個頗有意思的函數,咱們來看看兩個跟階乘相關的問題。
一、給定一個整數N,那麼N的階乘N!末尾有多少個0呢?例如:N=10,N! = 3628800,末尾就有兩個0
二、求N! 的二進制表示中最低位1的位置
 
咱們先分析第一個問題
咱們發現0的個數,就是10的個數,而10是由2跟5組成的,可是,5的個數明顯少於2,因此問題就轉換爲求5的個數。
 1 #include <iostream>
 2 using namespace std;
 3 // O(nlogn),思路:找0的個數,就是找10的個數,就是2*5的個數,2比5多,因此就是找5的個數,首先找到5的倍數,再判斷這些數裏面有多少個5
 4 int numOfZeros1(int n)
 5 {
 6     //i從1開始,當n爲26時,那麼i就是1,2,3,4,5
 7     //j就是5*i,因此對於的j就是5,10,15,20,25,第二個while循環找的就是j中有多少個5,像數字25,就有2個5
 8     //count表示的5的個數,即0的個數
 9     int i, j, count;
10     i = 1;
11     count = 0;
12     while (5 * i <= n)
13     {
14         j = 5 * i;
15         while (j % 5 == 0)
16         {
17             count++;
18             j = j / 5;
19         }
20         i++;
21     }
22     return count;
23 }
24 // o(logn),從時間複雜度上來講,優化的多。思路:n=26時,0的個數就是[26/25]+[26/5]=1+5=6
25 int numOfZeros2(int n)
26 {
27     int i, count;
28     i = 0;
29     count = 0;
30     while (n / 5)
31     {
32         count += n / 5;
33         n /= 5;
34     }
35     return count;
36 }
37 int main()
38 {
39     int n;
40     n = 125;
41     //test
42     cout<<numOfZeros1(n)<<endl;
43     cout<<numOfZeros2(n)<<endl;
44     system("pause");
45     return 0;
46 }

 

第二個問題的解答以下,分析也在代碼中了ios

 1 #include <iostream>
 2 using namespace std;
 3 // o(logn),在二進制中,乘以2就表示多一個0,因此,1最低位的位置其實就是2個個數+1
 4 int indexOfOne(int n)
 5 {
 6     int i, count;
 7     i = 0;
 8     count = 0;
 9     //這裏進行了一點點調整,更簡潔了,可對比上面的代碼,看看哪裏調整了
10     while (n)
11     {
12         //注意除以2,均可以用右移來標識哦!!
13         n = n >> 1;
14         count += n;
15     }
16     return count + 1;
17 }
18 int main()
19 {
20     int n;
21     n = 3;
22     //test
23     cout<<indexOfOne(n)<<endl;
24     system("pause");
25     return 0;
26 }
相關文章
相關標籤/搜索