1. 10億個數中取前1000大的數
維護一個1000個節點的小頂堆。
時間復雜度O(nlogk)
2. 合並k個有序(假設升序)數組
具體步驟:(1)將k個數組的第一個元素取出來,維護一個小頂堆。
(2)彈出堆頂元素存入結果數組中,並把該元素所在數組的下一個元素取出來壓入隊中。
(3)調整堆的結構,使其滿足小頂堆的定義。
(4)重復(2)(3)直到合並完成。
3. 給定一個正整數 N,需要把它分解成至少兩個不同的整數和,問有多少種不同的分解方案
動態規划:dp[n][m]表示n被分解為最大為m的數的方案數
\[dp\left[ n \right]\left[ m \right] = \sum\limits_{k = 1}^{m - 1} {dp\left[ {n - m} \right]\left[ k \right]} \]
4. 一個數組怎么輸出前K大的值、時間復雜度。
借助快排partition的思想,平均時間復雜度是O(n)
5. 查找數組中出現次數超過一半的數字
等價於求數組中第n/2大的數,和4中思想一樣,平均時間復雜度O(n)
6.二維數組查找(劍指offer)
在一個二維數組中(每個一維數組的長度相同),每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函數,輸入這樣的一個二維數組和一個整數,判斷數組中是否含有該整數。
思路分析:我們注意到這個二維數組的行和列都是升序的,也就是說最上面的一行和最右邊的一列在整體上也是升序的,在一個排序數組上查找某個我們會很自然的想起二分法。這樣我們每次都把要查找的數和當前剩下的二維數組的右上角數字比較,這樣每次我們都可以排除掉一行或一列。算法的時間復雜度是O(n+m),也就是行數加列數。
7.數組中插入數字
題一:替換空格(劍指offer)
請實現一個函數,將一個字符串中的每個空格替換成“%20”。例如,當字符串為We Are Happy.則經過替換之后的字符串為We%20Are%20Happy。
題二:兩個排序數組A1和A2,現在想把A2插入A1中並仍保持有序。
思路分析:數組是個順序表,我們往數組中插入某個數的話必須要移動當前位置后面所有的數。常規的思路是每次插入一個數並移動后面的數,這樣多次插入后會導致數組中有的數被移動了多次,極大浪費了效率。我們希望每個數移動一次就到達它最終的位置,所以我們往往會反向移動數組,這樣做的好處是移動當前數時后面的數已經到達了最終位置,我們移動當前數不會影響到后面的數,這樣就確保了每個數只被移動一次。
8. 合並兩個無序鏈表成一個有序鏈表,只能用常數空間。
歸並排序的思想,用快慢指針不斷二分鏈表。
9. 斐波那契數列高效計算
斐波那契數列:f(0) = 0, f(1) = 1, f(n) = f(n - 1) + f(n - 2)
方法一:遞歸,效率低
方法二:循環,正着推
方法三:矩陣運算
10. 用A表示1第一列,B表示2第二列,。。。,Z表示26,AA表示27,AB表示28。。。以此類推。請寫出一個函數,輸入用字母表示的列號編碼,輸出它是第幾列。
解題思路:26進制轉10進制。
11. 輸出一個整數二進制表示中1的個數
解法1:右移原數判斷,如果輸入是負數可能陷入死循環。
解法2:左移1
解法3:把一個整數-1后與原數做與運算會消去原數最左邊的1
12. 最小方差划分
把一個數組划分成兩部分,使其方差和最小。
D(X) = E(x^2) - [E(X)]^2
迭代求和。
13. 波蘭式和逆波蘭式相關問題
計算(1+((2+3)*(4*5))),leetcode224
14. 給定一個整數序列,你可以刪去其中的連續一段(可以不刪),求刪去后數組的最大連續子段和。(招商銀行M-Geeker競賽)
解題思路:最大連續子序列的變種題,從前往后遍歷一遍求最大連續子序列和,然后從后往前遍歷一遍求最大連續子序列和。
思路拓展:對於刪去中間一段不好直接操作的話,可以先從前往后遍歷,在從后往前遍歷。
15. 小明要在t分鍾之內做l張餅,有n個鍋,但只能選其中k個鍋,每個鍋每分鍾能做vi個餅,最多能做mi個餅,問能不能做完l張餅,如果能,輸出最少需要多少分鍾;如果不能,輸出最多能做幾張餅。
解法: 先討論能不能做完:每個鍋在t分鍾內能做的餅數為min(mi,vi*t), 降序排列,前k個鍋能做出來的餅>l就能; 如果不能做完:直接輸出前k個鍋能做餅的和;如果能:二分最短時間,然后判斷在mid分鍾內能不能做完餅,判斷方法同t分鍾的情況。
思路:查詢時先想一下二分。
16. O(1)時間刪除鏈表指定節點(給定單向鏈表的頭指針和一個節點指針)
解題思路:把該節點下個節點的值復制到該節點,刪除下個節點(注意該節點是尾節點和鏈表只有一個節點的特殊情況)