校招準備系列9 筆試面試演算法題

2021-08-28 18:41:42 字數 2558 閱讀 2726

可以先對一些簡單情形進行手工模擬,查詢規律

有時先對陣列進行排序可以使運算變得簡單,提高效率

字串問題、括號匹配問題,可以考慮逆向思維,從右往左看

從初態到某一狀態a最少需要幾步?可以考慮從狀態a回到初態的逆過程需要幾步

括號匹配,標準匹配正負之和count為0,允許一次交換則count下限調整為-1.

排列組合,組合數,排列數

數字的奇偶性

數的質因數分解

數的進製(解決稱藥片問題)

鍊錶判環:快慢指標。鍊錶相交:首尾交錯相連,p、q走到相遇為止。

裝箱問題,將貨物按重量從大到小排序,每次嘗試放最大的,放不下就開乙個新的箱子。

動態規劃需要找到遞推式,即狀態從i轉移到j的公式(狀態也可能是二維的(i1,j1)->(i2,j2))

動態規劃時,dp陣列中儲存的不一定是題目的要求,可以是「以每個位置結尾這種思維方式」

動態規劃:換錢的最少貨幣數(p191),換錢的方法數(程式設計師**面試指南p196,擴充套件:每種貨幣最多拿一次的情況),0/1揹包,完全揹包,裝箱問題

找錢的可能數(組合):每種錢幣0到無窮個,錢幣公升序排列,for j=1,n:;0~1個,錢幣降序排列,for j=n,1

走樓梯的方法數(排列):迭代法

打擂台。1.如果擂台上沒人,新人成為擂主。2.同一組人上台,擂主戰鬥力+1。3.不同組的人上台挑戰,擂主戰鬥力-1。4.最後留在台上的是中位數。

實現partial_sort的思想是:對原始容器內區間為[first, middle)的元素執行make_heap()操作構造乙個最大堆,然後拿[middle, last)中的每個元素和first進行比較,first內的元素為堆內的最大值。如果小於該最大值,則互換元素位置,並對[first, middle)內的元素進行調整,使其保持最大堆序。比較完之後在對[first, middle)內的元素做一次對排序sort_heap()操作,使其按增序排列。注意,堆序和增序是不同的。

時間複雜度:o(nlogk)=建堆o(k)+剩餘n-k個元素插入堆中o(nlogk)+對堆內元素進行堆排序o(klogk)

(擴充套件)

全部排序,o(nlogn)

氣泡排序或選擇排序找出前k個最小的元素,即每次冒泡(選擇)都能找到所求的乙個元素,找k次即可。這類策略的時間複雜度是o(kn)。

資料規模小,可以完全放到記憶體中,則可以用partition(但不是stl的partial_sort),不斷進行partition操作。平均時間複雜度o(n),最壞時間複雜度o(n2)

建立size為k的最小堆,每次遇到新元素則和堆頂元素(前k個元素中最小的那個)比較,如果比他大,則替換他,新元素下沉到合適的位置(o(logk))。總時間複雜度o(k)+o(nlogk)=o(nlogk).

可以先對資料進行hash分段,每一段生成乙個最小堆,再對這些最小堆用優先順序佇列(多路歸併)進行處理。

partition方法解決top-k問題

詳見:#include using namespace std;

// arr為陣列,start、end分別為陣列第乙個元素和最後乙個元素的索引

// povitindex為陣列中任意選中的數的索引

int partition(int arr, int start, int end)

}swap(arr[storeindex], arr[end]);

return storeindex;

}int findkth(int arr,int start, int end,int k)

else if(pivot_index > k)

else

}double findmid(int arr,int len)

else{

cout<<"even"《用findkth實現

兩個棧實現佇列。a棧用於入佇列,b棧用於出佇列,若b為空,則將a中的所有元素倒入b,再出佇列。

兩個佇列實現棧。如果「棧」非空,則必有一佇列非空。如果「棧」空,則

最大值棧:用乙個max棧來同步儲存可能的最大值在棧頂位置。入棧:max(當前最大值(即棧頂元素),新元素)。出棧:照常。

最大值佇列(滑動視窗最大值):用乙個max佇列來同步儲存可能的最大值在佇列頭位置。入佇列:將max佇列尾部比新元素小的元素依次出佇列,然後新元素入佇列。

(劍指offer都有的,可以去看看)

線段樹or樹形陣列(樹形分割槽),累加子分割槽的排名

1:戰力排行榜,幾乎實時得找出前100的玩家。(最大堆 和 計數排序),不知道有沒有修改和查詢都是o(1)得演算法?樹形陣列。

a. 一直維持乙個size為100的最小堆,外加乙個hashmap(儲存玩家id到節點的對映)。

儲存堆頂(第100名的戰力)的值,其餘玩家在更新積分時,如果超過了該值,插入堆(替換堆頂元素,下沉到合適位置)

b. 戰力分布集中在某個區間,例如0~200,那麼可以用計數排序的思想。使用陣列來儲存各個戰力的玩家,陣列的每個元素是乙個鍊錶。外加乙個hashmap(儲存玩家id到節點的對映)

c. 戰力分布很分散。將b中的陣列換成鍊錶,鍊錶的每個節點是乙個鍊錶。外加乙個hashmap(儲存玩家id到節點的對映)。

每次更新戰力,只需要沿著鍊錶前後找相鄰戰力鍊錶,放置到戰力鍊錶中合適的位置或者新開乙個鍊錶。

蘑菇街2019屆校招前端筆試演算法題

編寫乙個js函式,傳入乙個非空字串,計算出現次數最多的字元,返回該字元及 出現次數,結果可能包含多個字元。如傳入 xyzzyxyz 則返回 var str xyzzyxyz var chararray str.split var obj 用來存下所有的鍵和值 var max 0 用來記錄下出現最多的...

校招準備系列 每天一道演算法題(9) 單例

單例 是最為最常見的設計模式之一。對於任何時刻,如果某個類只存在且最多存在乙個具體的例項,那麼我們稱這種設計模式為單例。例如,對於 class mouse 不是動物的mouse哦 我們應將其設計為 singleton 模式。你的任務是設計乙個 getinstance 方法,對於給定的類,每次呼叫 g...

程式設計師筆試面試演算法題系列 陣列

1 遞迴實現陣列求和 void sum int a,int n,double sum 每次遞迴,在sum上累加,同時n自減,當n 0,退出遞迴。2 利用乙個for迴圈列印二維與三維陣列 double total row col for int k 0 k 3 遞迴判斷陣列是否遞增 return a ...