小羊的演算法養成日記

2022-10-10 13:03:15 字數 3594 閱讀 9394

45. 跳躍遊戲 ii

貪心演算法的經典問題,每次跳躍都盡量到達最遠的地方

48. 旋轉影象

計算機模擬題。矩陣順時針旋轉 = 沿對角線對稱 + 每行逆序

整個接的雨水量等於每個格仔所能接的雨水量之和。這仍然是窮舉的思路,只不過可以用雙指標來優化。

43. 字串相乘

計算機模擬題。先要模擬出解決問題的一般流程,然後再考慮**的實現。

37. 解數獨

39. 組合總和

40. 組合總和 ii

今天的三題全是回溯題。

回溯演算法其實套路比較明顯,無非就是列出選擇列表做選擇以及撤銷選擇。但是有些關鍵點還是需要注意:

回溯的本質還是窮舉,時間複雜度依然是指數級,非常耗時,所以我們要盡可能進行剪枝操作

不同思路對應著不同的回溯邏輯,相應的時間開銷也可能不同

34. 在排序陣列中查詢元素的第乙個和最後乙個位置

二分查詢看似簡單,但細節很多。需要明確查詢的區間是 [left, right) 左閉右開,並且基本二分查詢演算法的返回值是陣列中第乙個大於等於 target 的元素下標,可能的範圍為[0, nums.length]

28. 實現 strstr()

經典字串匹配問題

用雙指標技巧可以進行暴力匹配,時間複雜度為 o(mn)

另有kmp演算法,時間複雜度為o(m),空間複雜度為o(n) [m為文字串長度,n為模板串長度]

kmp演算法實際上是利用了之前已經匹配的結果,也就是利用了過去的結果(dp思想),來實現不回退文字串指標,只更改模板串的待匹配位置。可以利用dfa的思想,來對模板串進行分析處理。**如下:

class solution else

}// 在進入下一狀態之前,先進行影子狀態的推進

x = dp[x][needle.charat(i)];

// 如果能推進,說明此時x和i狀態都具有相同的字首(從右往左看)x也就是i的影子狀態

}int j = 0;

for(int i = 0;i < m;i++)

}return -1;

}}

其中的影子狀態是核心,舉個例子,當我們的模板串是ababc時候,c匹配失敗了,那麼模板串會從頭開始匹配嗎?並不會。因為c匹配失敗的時候,前面的abab匹配還是成功的,我需要利用這個資訊。我接下來只需要從模板串的第二個a處開始重新匹配就行了,這也是kma演算法的核心思想。

25. k 個一組翻轉鍊錶

這一題讓我理解了遞迴的意義。之前做過這道題,用的是迭代的思路。在迭代過程中,有很多很多的細節問題,稍不留神,就寫出bug了。

這次採用的是遞迴的思路,遞迴的思想就在於在方法內部呼叫自身

首先先明確本方法的意義:將以head結點為頭結點的鍊錶k個一組進行翻轉,返回值是翻轉後的煉表頭結點。然後進行自我呼叫就可以了,遞迴的**非常得優美,我貼出來共同欣賞:

class solution {

public listnode reversekgroup(listnode head, int k) {

if(head == null) return null;

listnode end = head;

for(int i = 0;i26. 刪除有序陣列中的重複項

27. 移除元素

和陣列有關的題目,用雙指標技巧比較多。維護乙個前後指標,就可得出答案。

21. 合併兩個有序鍊錶

23. 合併k個公升序鍊錶

合併鍊錶,合併陣列,簡單來說就是乙個乙個比,指標不斷推進,直至遍歷完畢。合併k個鍊錶的難點在於,我們不知道到底該合併多少個鍊錶,也就不知道每次怎麼比。這個時候就可以借助優先佇列,把所有鍊錶的頭結點放進去,佇列內部自動進行排序。每次取出乙個最小的,就把該結點的next結點重新放進去,直至隊列為空。

22. 括號生成

利用了括號匹配的隱藏結論:在匹配成功的過程中,左括號的數目一定大於等於右括號的數目。所以,在回溯遍歷全部可能性的同時,依據此必要條件進行剪枝。

19. 刪除鍊錶的倒數第 n 個結點

鍊錶題目,比較固定的思路:

如果說可能會刪除頭結點,就用乙個虛擬頭節點dummy

基本上鍊表題目必用技巧

想要只遍歷一次,來獲得相對於末尾的某個位置的結點,就用快慢指標

快慢指標還可以用來解決環形鍊錶問題

20. 有效的括號

經典有關棧的題目,括號匹配問題

明確匹配失敗的兩個場景:

當遇到右括號時,符號棧內為空或者棧頂符號不是對應的左括號

當匹配完成時,符號棧內仍存在剩餘左括號

括號匹配還有乙個隱藏結論:在匹配成功的過程中,左括號的數目一定大於等於右括號的數目。此結論是解決其它括號問題的基礎。

11. 盛最多水的容器

容器的長和高,均為變數。可以使用雙指標技巧,首先給出乙個範圍最廣的初始解,然後不斷地嘗試去縮小範圍,以得到最優解。

刷題的時候想到了線性規劃單純形法,先確定乙個初始解,然後不斷朝著可能更優的方向迭代——凸優化問題

15. 三數之和

18. 四數之和

經典towsum問題的延申,towsum問題給人兩點啟示:

對於需要極高的查詢效能時,不妨想想能否使用hashmap/hashset

對於陣列亂序的情況,一般情況下都要排序+雙指標,否則只能窮舉

5. 最長回文子串

這一題是對雙指標技巧的應用。回文串也就是順著讀和倒著讀都一樣的字串,如果想要乙個最長的回文子串,那麼窮舉是必不可少的。字串中每個字元都可能為回文的中心點,當然進一步細分還會分奇回文和偶回文。總的來說,思路就是將每個字元都看成中心點,從中心向兩邊擴散,不斷更新最優解。在擴散的時候,就用到了雙指標的技巧。

10. 正規表示式匹配

這一題用動態規劃求解。先分析問題,模擬出正規表示式的匹配過程。在畫出匹配過程後,就可以發現問題與子問題的關係,就可用動態規劃求解。其實dp的難點在於如何刻畫出情況(狀態),以及如何通過已知情況解出當前情況的解(狀態轉移)。總的來說,分析清楚問題是最為關鍵的。只有成功模擬出匹配的過程,才能刻畫出「情況」,才能進**況的演化。

567. 字串排列

438. 找到字串中所有字母異位詞

今天這兩題是滑動視窗中的固定視窗型別

在乙個字串s中找尋另乙個字串p的排列

事實上也就是維護乙個大小固定為字串p長度的視窗

控制區間 [left, right) 的大小

3. 無重複字元的最長子串

76. 最小覆蓋子串

今天這兩題是滑動視窗題目

滑動視窗的核心在於兩點:

什麼時候擴大視窗(右邊界++)?

什麼時候縮小視窗(左邊界++)?

並且要注意,視窗最好使用左閉右開區間去定義[left, right)

Linux養成日記 2014 6 30

linux的學習總是斷斷續續的,一直都沒辦法把工作環境完全移植到linux下,暑假打算徹底學習一下。簡單記錄下學習過程中的一些心得。ubuntu版本 ubuntu 12.04.4 lts ubuntu 12.04.4 desktop i386.iso 設定root使用者密碼 sudo passwd ...

大魔王養成日記

這裡是大魔王平時折 騰 的紀實 加得越多,完成進度就慢 廖雪峰git教程 這個教程較為簡單,循序漸進 易百git教程 較為系統 git教程優先選擇廖雪峰git教程 ls rmmkdir chmod catvimvim簡明教程 coolshell 為什麼不用emac?不為什麼,只因我先遇到了vim。g...

乙隻程式猿的養成日記 第一章 第六節 棧幀結構

第一步 初始化 建立mian函式的棧幀結構。第二步 初始化 儲存 變數 a 第三步 初始化 儲存 變數 b 第四步 將變數 b 的值儲存到 暫存器 eax 並將 暫存器壓入 main 函式的棧幀中。第五步 將變數 a 的值儲存到 暫存器 ecx 並將 暫存器壓入 main 函式的棧幀中。2,隨即,跳...