《程式設計之美》讀書筆記(一)

2022-01-31 03:38:12 字數 3111 閱讀 4426

2.1求二進位制數中1的個數

乙個8byte的整數,求其二進位制表示中1的個數。

四個演算法:

1)迴圈除2判斷餘數是否為1

2)和0x01異與(&),判斷最後一位是否為1,然後右移一位,迴圈往復。

演算法1和2的時間複雜度都是o(logn)

3)這個演算法比較狠,乙個乙個抹去最後乙個1,這樣時間複雜度就只和1的個數有關。

主要是n & (n-1) ,這個技巧很重要,能計算出末尾最後乙個1的位置。

while(v)

n = n & (n-1)

num++;

return num;

4)8byte,它的值只有256種可能,所以更狠的做法是做乙個int[256]的陣列,把這些值事先都對號入座,然後arr[i]隨便取哪個,時間複雜度o(1)。

話說,32位的演算法,不是科班出身的我,並沒有看懂。

另一道擴充套件題目,是先對a和b做異或,然後再計算結果值中1的個數。

c#程式設計師們,牢記啊:

|運算規則:0^0=0; 0^1=1; 1^0=1; 1^1=0 簡單地說,有1位為1就是1

不要和xor混,後者相同時為0,不同為1。

&與運算規則:只有都為1,才是1;否則,一概返回0。

2.2 不要被階乘嚇倒

第一道題,n!末尾有幾個0?

其實就是在算有多少個5。[n/5]+[n/25]+[n/125]+……,其中[n/5]表示從1到n中,有多少可以被5整除的數?

這是一種「扒皮抽筋」的思想:

ret=0

while(n)

ret += n / 5;

n /= 5;

第2道題,n!的二進位制表示中,從末尾向前,第乙個1的位置?

其實就是計算從1到n有多少個2的質因數——有x個2,那麼n!的二進位制末尾就有x個0,那麼第乙個1的位置就是n+1。

繼續使用「扒皮抽筋」的思想:[n/2]+[n/4]+[n/8]+……

擴充套件題目:判斷n是否為2的方冪?

n & (n-1) == 0,當然,還要同時保證n〉0;

2.3 尋找發帖水王

每次刪除2個不同的id,這個演算法很有意思,比如說a、a、b、c、a、b、a、a,那麼ntimes先公升到2,然後,因為b、c的出現,又降到0,於是重新制定candidate。最後ntimes總會大於0,candidate不再變化。

擴充套件題目太複雜了,我建議範圍縮小為:有2個發帖很多的id,都已超過了1/3,如何找出?思路仍然是,每遇到3個不一樣的就殺一次,從而保證,仍然有2個id都超過1/3。

於是我們要建立陣列:ntimes[0]和ntimes[1],要建立相對應的值candidate[0]和candidate[1],說一下過程:

比如說前三個數是a、a、b,那麼candidate[0]=a,candidate[1]=b,ntimes[0]=2,ntimes[1]=1,下面問題就來了,

如果第4個數是a或b,就相應增加ntimes[0]和ntimes[1]的數量值。

如果第4個數是c,分別和candidate[0]和candidate[1]比較都不一樣,於是我們認為找到了3個不一樣的數,殺掉,殺的過程是ntimes[0]和ntimes[1]都減去1,如果其中哪個變成了0,就清除相應的candidate,這裡ntimes[1]減去1後變成了0,所以candidate[1]要清空,等待下乙個值進來。

這樣迴圈下去,最後candidate[0]和candidate[1]就是我們要找的兩個水王。

擴充套件題目的要求是找3個發帖超過1/4的id,可以按照我剛才的思路玩下去。

由此題可見分治、貪心、遞推思想的妙處。

2.4 「1」的數目

計算f(n)中1的個數,這道題目告訴我們,列舉+歸納法的重要性。大體列舉到4位數,就能歸納出之後的所有情況了。第n位上出現1的次數,由3種因素決定:n位上的數字、n位以上的數字、n位以下的數字。

於是對第n位上的數字,分3種情況討論:

1)為0:更高位數字x10的n次方

2)為1:不僅由高位決定:更高位數字x10的n次方;還要受低位影響:當前n位及以下的值+1

3)大於1:(更高位數字+1)x10的n次方

計算f(n)=n

我對書中的解法不同意。算出10的11次方這個上界,是可以接受的,但是接下來用遞減的方式找出n,是很費勁的。我建議使用二分法,o(longn)的效率要比o(n)快很多。

擴充套件題目分析:本題目的二進位制方式

2.5 尋找最大的k個數

唉,又是排序,惡補一通排序演算法的知識先。唉,不是科班出身的人就是吃虧啊,如果有來生,但是,我連程式設計師這一行都不一定做。

2.6 精確表達浮點數

2.7 最大公約數問題

輾轉相除法不好,輾轉相減法也不好。

遇到0就右移,都是1就相減,直到有乙個為0。

2.8 找符合條件的整數

2.9 fib數列

其實我最喜歡用空間換時間,不管是f(n)=f(n-1)+f(n-2),還是f(n)=f(n-1)+f(n-2)+f(n-3)。

當然,用單位矩陣的n次冪,也是乙個好辦法。

2.10

找出陣列中的最大最小數:貌似最快只能是1.5n,誰讓最大和最小距離那麼懸殊。

找出n個陣列中的最二大數:兩個兩個一組排序,大的在前(奇數字),只要奇數字的,排成乙個新的陣列(概念上)——繼續反覆,直到剩下4-5個。

如何從n個數中選出最大(小)的n個數?

敗者樹(loser tree)

2.11 尋找最近點對

2.20 程式理解和時間分析

2.21 只考加法的面試題

3.1 字串移位包含的問題

如果s2可以由s1迴圈移位得到,那麼s2一定在s1s1上

貌似有乙個演算法,叫做「最小表示法」

3.2 **號碼對應英語單詞

3.3 從無頭單鏈表中刪除節點

狸貓換太子:

curr.data = curr.next.data;

curr.next = curr.next.next;

3.6

「鍊錶相交」擴充套件問題

單鏈表反轉問題:

讀書筆記 程式設計之美(一

不得不說程式設計之美是一本很有意思的書,裡面的各式各樣新奇的問題,總是可以通過課上講的簡單的問題來解決,對於訓練自己的思維的確有很大的好處。一般解決複雜的問題,我們總是可以通過 1 畫圖 鍊錶 二叉樹,2 舉例,3 分解 分治法 動態規劃來解決。for 遍歷a的位置 遍歷b的位置 判斷a b的位置組...

《程式設計之美》讀書筆記

程式設計之美 讀書筆記 一 中國象棋將帥問題 程式設計之美 讀書筆記 二 求二進位制數中1的個數 擴充套件問題 程式設計之美 讀書筆記 三 一摞烙餅的排序問題 程式設計之美 讀書筆記 四 買書折扣問題的貪心解法 程式設計之美 讀書筆記 五 飲料 問題 程式設計之美 讀書筆記 六 連連看遊戲設計 程式...

《程式設計之美》讀書筆記集錦

程式設計之美 讀書筆記 一 中國象棋將帥問題 程式設計之美 讀書筆記 二 求二進位制數中1的個數 擴充套件問題 程式設計之美 讀書筆記 三 一摞烙餅的排序問題 程式設計之美 讀書筆記 四 買書折扣問題的貪心解法 程式設計之美 讀書筆記 五 飲料 問題 程式設計之美 讀書筆記 六 連連看遊戲設計 程式...