【演算法拾遺】階乘
轉載請註明出處:http://blog.csdn.net/ns_code/article/details/28335353
前言
主要看兩道有關階乘的題目,從中可以看出一些規律來。
題目一
N!末尾0的個數
找末尾0出現的個數,那我們就要找產生0的乘數,即哪些數相乘會得到10。我們需要對N!進行質因數分解,由於10 = 2*5,因此0的個數至於N!中2和5出現的的對數有關,而能被2整除的數出現的頻率比能被5整除的數要多得多,因此我們找出N!中質因數5出現的個數,即為N!末尾0的個數。
方法一
最直接的方法,就是計算1-N中每個數的因式分解中5的個數,然後相加,程式碼如下:
int FactorialNum0_1(int n)
{
int count = 0;
int i;
for(i=1;i<=n;i++)
{
int j = i;
while(j%5 == 0)
{
count++;
j /= 5;
}
}
return count;
}
這種方法的時間複雜度為O(n)。方法二
方法一中對不含質因數5的數也進行了判斷,時間複雜度較高。
第二種方法要用到如下結論:
N!中含有的質因數k的個數為:[N/k]+[N/k^2]+[N/k^3]+...(總會存在一個t,使得k^t>N,便有[N/k^t]=0)
這個公式的證明並不難,自己嘗試去理解下,其中[N/k]等於1,2,3...N中能被k整除的數的個數。
用該方法寫成的程式碼如下;
int FactorialNum0_2(int n)
{
int count = 0;
while(n)
{
count += n/5;
n /= 5;
}
return count;
}
該方法的時間複雜度為O(log5n)(這裡是以5為底n的對數)。題目二
N!二進位制表示中最低位1的位置
比如3!為6,二進位制為1010,那麼最低位的1的位置為2,這裡最左邊的位置從1開始計算。
方法一
我們假設最低位的1的位置為第k位,則N!=2^(k-1)+...+2^t+...+2^p+...,這裡t,p等意味著後面的第t+1位,第p+1位也為1,且p>t>k。這樣很容易看出來,N!中質因數2的個數為k-1個,也就是說,最低位1的位置即為N!中質因數2的個數加1,因此問題又轉化為了求N!中質因數2的個數了,同樣利用結論:
N!中含有的質因數k的個數為:[N/k]+[N/k^2]+[N/k^3]+...(總會存在一個t,使得k^t>N,便有[N/k^t]=0)
這樣寫出的程式碼如下:
int Lowest1(int n)
{
int count = 0;
while(n)
{
count += n/2;
n /= 2;
}
return count + 1;
}
該方法時間複雜度為O(log2n)(這裡是以2為底n的對數)。方法二
用如下結論:N!中含有質因數2的個數,等於N減去N的二進位制表示中1的個數,關於如何求N的二進位制表示中1的個數,參考我的這篇博文;http://blog.csdn.net/ns_code/article/details/25425577,最快的方法的操作步驟只與二進位制中1的個數相等,因此這種方法的時間複雜度更好一些,雖然方法一已經很快了,這種方法的時間複雜度為O(k),其中k為N!中1的個數。這種方法的程式碼不再給出。
相關文章
- [MASM拾遺]OffsetASM
- 前端技能拾遺前端
- Java Web 拾遺JavaWeb
- 物件導向拾遺物件
- OrchardCore Headless建站拾遺
- [資料結構拾遺]字串排序演算法總結資料結構字串排序演算法
- Confluence 容器化使用拾遺
- docker拾遺-之再入坑Docker
- 容器化 Confluence 使用拾遺
- golang拾遺:嵌入型別Golang型別
- Vue.js基礎拾遺Vue.js
- PHP 使用 Kafka 安裝拾遺PHPKafka
- AS拾遺--向PM學習二
- golang拾遺:指標和介面Golang指標
- 語言演算法之:階乘演算法
- 課時39:類與物件:拾遺物件
- C#拾遺補闕【01】:字串C#字串
- Python中物件導向程式設計的一些高階方法拾遺Python物件程式設計
- 【105天】前端碎片知識拾遺00003前端
- 【106天】前端碎片知識拾遺00004前端
- JAVA 拾遺 — CPU Cache 與快取行Java快取
- Zepto核心模組之工具方法拾遺
- JSON實戰拾遺之數字精度JSON
- mysql 拾遺提高(函式、事務、索引)MySql函式索引
- React拾遺:Render Props及其使用場景React
- 前端拾遺--javascript-ES6基礎前端JavaScript
- (零) React Native 專案開發拾遺React Native
- [Go]Go 語言基礎拾遺(一)Go
- MIT 6.824拾遺(一)聊聊basic-paxosMIT
- iOS拾遺—— Assets Catalogs 與 I/O 優化iOS優化
- JAVA拾遺 — JMH與8個測試陷阱Java
- Git拾遺:一機多SSH-Key管理Git
- 基礎拾遺---委託,匿名函式,lambda函式
- [C#.NET拾遺補漏]01:字串操作C#字串
- 2萬字 | 前端基礎拾遺90問前端
- 【刷演算法】LeetCode- 階乘後的零演算法LeetCode
- golang拾遺:為什麼我們需要泛型Golang泛型
- Netty拾遺(七)——粘包與拆包問題Netty
- 【C++】 68_拾遺: 令人迷惑的寫法C++