可以先對一些簡單情形進行手工模擬,查詢規律
有時先對陣列進行排序可以使運算變得簡單,提高效率
字串問題、括號匹配問題,可以考慮逆向思維,從右往左看
從初態到某一狀態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 ...