程式設計之美題選

2021-06-30 16:35:48 字數 3112 閱讀 5526

1、求二進位制數中1的個數:

1、除以2 根據餘數 判斷,迭代 

2、與1相與,根據結果判斷,迴圈移位 

3、列出全部資料對映2-1 3-2 4-1 。。。 建立hash表o(1)

4、(1100&1011=1000 能去掉最右邊的1)

intnumber(int n )

}

2、求出陣列中個數超過一半的數字a

每次刪除2個不同的數字,那麼在剩下的數字中,a仍會超過總數的一半。

int find(int id, int n)

else

}return candidate;

}

現在有3個發帖水王,發帖數目都超過了總數的1/4,怎麼找出這三個人?

現在我們需要3個變數來記錄當前遍歷過的3個不同的id,而ntimes的3個元素分別對應當前遍歷過的3個id出現的個數。如果遍歷中有某個id不同

於這3個當前id,我們就判斷當前3個id是否有某個的ntimes為0,如果有,那這個新遍歷的id就取而代之,並賦1為它的遍歷數(即ntimes減1)

,如果當前3個id的ntimes皆不為0,則3個id的ntimes皆減去1。

3、n個數字中取出前k大的數;

方法一:

1、用快排的思想,a[0]為基準,劃分陣列為sa都大於a[0],sb都小於a[0]

2、若|sa|k,則sa中的前k個數就是陣列的前k大

4、這樣遞迴下去,不斷把問題分解為更小的子問題,平均複雜度為o(n*logk)

方法二:

用最小堆時間複雜度也是o(n*logk)

空間複雜度是o(k)

在n非常大,資料需要儲存在磁碟上,而k相對很小,可以在記憶體上輕易維護大小為k的堆的情況下,在減少磁碟i/o上會有一定的優勢,因為每個

元素只需要被讀取一次。

4、得到陣列的最大值和最小值:

方法一:每2個數字比較,大的放在偶數字,小的在奇數字,在各自求極值,1.5n的複雜度

方法二:每2個數字比較,大的再和max比較,小的再和min比較,不用破壞陣列,也是1.5n。

方法三:也可以用分治,求前後n/2的min和max,小小比較得到min,大大比較得到max,遞迴

5、求二維平面上n個點,距離最小的2點

方法一:窮舉o(n^2)

方法二:分治法,中點x對半分成2個區域,分別求最小得出min,但可能出現左右2邊有2點間距最小,只考慮在[x-min,x+min]內的點,以此解法

遞迴求解

陣列中取出2個數的和等於給定值a

方法一:o(n^2) a[i]+a[j]==a? 或者用a[j]==a-a[i]?

方法二:消耗o(n)的空間儲存hash表,根據對映查詢a-a[i]是否在表中

方法三:先排序o(nlogn),再用雙指標left(0), right(n-1)指向2端,若之和大於a則right移動

否則left移動。

6、n-1子陣列的最大乘積

不急分情況討論:(n個數的乘積)

1、p=0 再分情況:q為n-1個數的乘積

q=0解為0

q<0解為0

q>0為解

2、p<0去掉絕對值最小的那個負數即可

3、p>0去掉絕對值最小的那個正數

(+暴力破解)o(n^2)

7、求子陣列最大和:

方法一:暴力o(n^3)

方法二:分治法:

a[n]最大欄位和值為三種情況:

1、a[n/2-1]的最大欄位和

2、a[n/2]到a[n]的最大欄位和

3、最大欄位和橫跨a[n/2-1]和a[n/2](卡中間,計算sum=sum1+sum2)

方法三:動態規劃法

//如果sum>max 則更新max

//如果sum<0 則 更新sum為0 繼續迴圈

//否則是0for(int i=1;i<=t;i++)

//max儲存全域性最大,sum隨著指標移動而變化,為負數則置0

//找到更大的則賦給max,max始終儲存全域性最大

8、求陣列中最長遞增子串行:

前i個元素中最長遞增子串行為lis[i]

則有:lis[i+1]=max

for(int i=0;iarr[j]&&lis[j]+1>lis[i])

lis[i]=lis[j]+1; }}

return max(lis);

9、陣列迴圈右移k位,複雜度o(n),最多允許使用2個變數

abcd1234右移4位->1234abcd

前4位逆序排列 abcd1234->dcba1234

後4位逆序排列dcba1234->dcba4321

全部逆序dcba4321->1234abcd

reverse(int* arr,int b,int e){

for(;b(沒要求空間複雜度才可以建立乙個新的陣列直接o(n)copy過去)

一位一位移動的複雜度是o(k*n)

10、陣列分割:使得2份之和 盡量接近

11、字串移位包含:

1、暴力破解

2、判斷s2是否是s1的移位包含,可以將2個s1連起來以避免移位。

aabcd aabcd包cdaa 空間換時間

12、從無頭單鏈表中刪除節點:

假設乙個沒有頭指標的單鏈表。乙個指標指向此單鏈表中間的乙個節點p(不頭不尾),要刪除該節點p

"狸貓換太子":可以把p節點後面的節點q的value賦值到p節點,

然後刪除節點q即可

q=p-next;

p->data=q->data;

p-next=q-next;

13、判斷2個鍊錶a,b是否相交:

1、暴力解法 依次判斷a中節點是否在b中,複雜度o(length(a)*length(b))

2、用hash建立其中乙個鍊錶的節點位址查詢hash表

3、可以將b煉表表頭連線在a表的後面,在判斷鍊錶是否有環

4、直接判斷最後乙個節點是否是同一節點,複雜度o(length(a)+length(b))是最快捷的解法

(怎樣找到第乙個公共結點?)鍊錶長的-短的=i 長的先走i步,然後一起走,每步判斷結點是否相同

14、重建二叉樹:根據前序和中序

15、分層遍歷二叉樹:

程式設計之美2015第一題

給定兩個日期,計算這兩個日期之間有多少個2月29日 包括起始日期 只有閏年有2月29日,滿足以下乙個條件的年份為閏年 1.年份能被4整除但不能被100整除 2.年份能被400整除 第一行為乙個整數t,表示資料組數。之後每組資料報含兩行。每一行格式為 month day,year 表示乙個日期。mon...

推薦《程式設計之美》

推薦 程式設計之美 我很早知道鄒欣計畫要寫這樣一本書,也能夠預計到這本書定會廣受歡迎,因為它符合當前大量求職人員的需求,畢竟於他們而言,誰不想知道微軟亞洲研究院在招人時候問些什麼問題呢。另一方面,把考察軟體技術人員專業知識和相應技能的各種手段加以歸納和整理,這本身也是對業界的貢獻,所以,我相信,一旦...

程式設計之美摘錄

第1章 遊戲之樂 遊戲中碰到的題目 1.1讓cpu佔用率曲線聽你的指揮 int main return 0 解法二 使用gettickcount 和sleep 解法三 能動態適應的解法 1.2中國象棋將帥問題 1.3一摞烙餅的排序 1.4買書問題 1.5快速找出故障機器 1.6飲料供貨 1.7光影切...