Leetcode, Codility , GeekforGeeks algorithms exercises written in Golang.
https://kimi0230.github.io/LeetcodeGolang/
leetcode Content
- Leetcode in Golang
- leetcode Content
- GeeksforGeeks Content
- Codility Content
- Reference
| No. | Title | Solution | Difficulty | Time | Space | Topic |
|---|---|---|---|---|---|---|
| 0001 | Two Sum | Go | Easy | O(n) | O(n) | Array |
| 0003 | Longest Substring Without Repeating Characters | Go | Medium | O(n) | O(1) | Array, Sliding Window |
| 0015 | 3 Sum | Go | Medium | O(n^2) | O(n) | Array |
| 0027 | Remove Element | Go | Easy | O(n) | O(1) | Array |
| 0035 | Search Insert Position | Go | Easy | O(n), O(logn) | O(1) | Array |
| 0049 | Search Insert Position | Go | Medium | O(kn) | O(kn) | Array |
| 0059 | Spiral Matrix II | Go | Medium | O(n) | O(n^2) | Array |
| 0088 | Merge Sorted Array | Go | Easy | O(n) | O(1) | Array |
| 0217 | 0217.Contains Duplicate | Go | Easy | O(n) | O(n) | Array |
| 0242 | 0242.Valid Anagram | Go | Easy | O(n) | O(n) | Array |
| 0409 | 409. Longest Palindrome | Go | Easy | O(n) | O(1) | Array |
| 0380 | 0380.Insert Delete GetRandom O(1) | Go | Medium | O(1) | O(n) | Array |
| 0381 | 0381.Insert Delete GetRandom O(1) Duplicates allowed | Go | Medium | O(1) | O(n) | Array |
| 0412 | 0412.Fizz Buzz | Go | Easy | O(n) | O(n) | Array, string |
| 1195 | 1195.Fizz Buzz Multithreaded | Go | Medium | O(n) | Array, string,Concurrency | |
| 0238 | 238. Product of Array Except Self | Go | Medium | O(n) | Array, string, Prefix Sum | |
| 0128 | 128. Longest Consecutive Sequence | Go | Medium | O(n) | O(n) | Array, Hash Table, Union Find |
| No. | Title | Solution | Difficulty | Time | Space | Topic |
|---|---|---|---|---|---|---|
| 0019 | Remove Nth Node From End of List | Go | Medium | O(n) | O(1) | Linked List, Two Pointers |
| 0141 | Linked List Cycle | Go | Easy | O(n) | O(1) | Linked List, Two Pointers |
| 0142 | Linked List Cycle II | Go | Medium | O(n) | O(1) | Linked List, Two Pointers |
| 0203 | Remove Linked List Elements | Go | Easy | O(n) | O(1) | Linked List |
| 0206 | Reverse Linked List | Go | Easy | O(n) | O(1) | Linked List |
| 0876 | Middle of the Linked List | Go | Easy | Linked List, Two Pointers | ||
| 0021 | Merge Two Sorted Lists | Go | Easy | O(log n) | O(1) | Linked List |
| 0002 | Add Two Number | Go | Medium | O(max(m,n)) | O(1) | Linked List |
| No. | Title | Solution | Difficulty | Time | Space | Topic |
|---|---|---|---|---|---|---|
| 0020 | Valid Parentheses | Go | Easy | O(n) | O(n) | Stack |
| 0094 | Binary Tree Inorder Traversal | Go | Medium | O(n) | O(1) | Stack |
Heap 總是能讓整棵樹當中最大或最小值維持在root節點上
- 常見架構是像 binary tree 那樣
- 保持 balanced
- max heap 的 root 是最大值;min heap 的 root 則是最小值
- 雖然是 tree,卻很適合放在 array 中處理
根據定義 heap 的 root 一定是最大(假設是 max heap),也就是說,無序數列經過 heapify 再作 n 次 root deletion 取出最大值,就可以得到排序的結果。 最後就得到 heap sort 的 worst case 時間複雜度 O(nlogn) 的結果。 可是 quick sort 的 worst case 時間複雜度是 O(n²),怎麼 quick sort 的時間複雜度比較糟糕卻比較受歡迎? google 的結果是說 heap sort 比較不利於 caching 對於 spatial locality 機制,蠻有道理的阿。
| No. | Title | Solution | Difficulty | Time | Space | Topic |
|---|---|---|---|---|---|---|
| 0703 | Kth Largest Element in a Stream | Go | Easy | O(K + (N-K)logK) | O(k) | Heap, Priority Queue |
| 1046 | Last Stone Weight | Go | Easy | O(nlogn) | O(n) | Heap, Priority Queue |
| 0347 | Top K Frequent Elements | Go | Medium | O(Nlogk) | O(n) | Heap, Priority Queue, Quick Sort |
| No. | Title | Solution | Difficulty | Time | Space | Topic |
|---|---|---|---|---|---|---|
| 0075 | Sort Colors | Go | Medium | O(n) | O(1) | Sort |
| 0215 | Kth Largest Element in an Array | Go | Medium | O(n) | O(logn) | Sort |
DFS. 解決一個回溯問題, 實際上就是一個決策樹的遍歷過程. 算是一個暴力的窮舉算法
- 路徑:也就是已經做出的選擇。
- 選擇列表:也就是你當前可以做的選擇。
- 結束條件:也就是到達決策樹底層,無法再做選擇的條件。
- https://www.bilibili.com/video/BV1P5411N7Xc
result = [] def backtrack(路徑, 選擇列表): if 滿足結束條件: result.add(路徑) return for 選擇 in 選擇列表: 做選擇(前序) backtrack(路徑, 選擇列表) 撤銷選擇(後序)| No. | Title | Solution | Difficulty | Time | Space | Topic |
|---|---|---|---|---|---|---|
| 0046 | Permutations (全排列) | Go | Medium | O(n) | O(n) | Backtracking |
| 0078 | Subsets | Go | Medium | O(n^2) | O(n) | Backtracking |
找最短路徑用BFS, 其他時用DFS用得多一些, 因為遞迴較好寫
假設有棵滿的二叉樹,節點數為 N. 對DFS來說空間複雜度就是遞迴, 最壞的情況就是樹的高度 O(log N) BFS算法, Queue每次都會存二叉樹一層的節點, 最壞的情況下空間複雜度應該就是樹的最下層的數量, 也就是 N/2. 空間複雜度 O(N)
DFS(深度優先搜索)通常使用堆棧(Stack)來實現。在DFS中,您首先處理一個節點,然後將其子節點按某種順序推入堆棧中,接著繼續處理堆棧頂部的節點,直到堆棧為空。 BFS(廣度優先搜索)則使用隊列(Queue)來實現。在BFS中,您首先處理一個節點,然後將其子節點按某種順序排隊,接著繼續處理隊列的前端節點,直到隊列為空。
| No. | Title | Solution | Difficulty | Time | Space | Topic |
|---|---|---|---|---|---|---|
| 0695 | Max Area of Island | Go | Medium | O(m*n) | O(m*n) | DFS & BFS |
| 0733 | Flood Fill | Go | Easy | O(m*n) | O(m*n) | DFS & BFS |
動態規劃問題的一般形式就是求最值, 最長遞增子序列, 最小編輯距離等. 核心問題是窮舉
- 重疊子問題
- memory table
- DP table
- 最優子結構
- 狀態轉移方程式
- 這問題的 base case (最簡單情況) 是什麼?
- 這問題有什麼狀態
- 對於每個狀態, 可以做出什麼選擇, 使得狀態發生改變
- 如何定義 dp 數組/函數的含義來表現狀態和選擇?
| 替換 /跳過 dp[i-1][j-1] | 刪除 dp[i-1][j] |
|---|---|
| 插入 dp[i][j-1] | dp[i][j] |
# 初始化 base case dp[0][0][...] = base # 進行狀態轉移 for 狀態1 in 狀態1的所有取值: for 狀態2 in 狀態2的所有取值: for ... dp[狀態1][狀態2][...] = 求最值(選擇1,選擇2...)| No. | Title | Solution | Difficulty | Time | Space | Topic |
|---|---|---|---|---|---|---|
| 0053 | Maximum Subarray | Go | Easy | O(n) | O(n) | Dynamic Programming |
| 0072 | 0072. Edit Distance | Go | Hard | Dynamic Programming | ||
| 0300 | Longest-Increasing-Subsequence | Go | Medium | 方法一:O(n^2) 方法二:O(nlogn) | O(n) | Dynamic Programming |
| 0322 | Coin Change | Go | Medium | O(nm) | O(n) | Dynamic Programming |
| 0354 | Russian Doll Envelope | Go | Hard | Dynamic Programming | ||
| 0509 | Fibonacci Number | Go | Easy | 很多解法 | 很多解法 | Dynamic Programming |
| 0070 | 0070.Climbing Stairs | Go | Easy | O(n) | O(n) | Dynamic Programming |
| 0746 | 0746.Min Cost Climbing Stairs | Go | Easy | O(n) | O(1) | Dynamic Programming |
維護一個窗口, 不斷滑動
void slidingWindow(string s, string t){ unordered map<char,int>need, window; for (char c:t) need[c++] int left = 0 , right = 0 int valid = 0 // 先移動 right 再移動 left. 直到right到達 string的末端 while(right < s.size()){ // c是將移入窗口的字符 char c = s[right] // 右移窗口 right++ // 進行窗口內數據的一系列更新 // ... /*** 用來debug 輸出位置 ***/ printf("window: [%d, %d)\n",left,right) /************************/ // 判斷左側窗口是否收縮 while(window needs shrink){ // d是將移出窗口的字符 // 左移窗口 left++ // 進行窗口內數據的一系列更新 // ... } } }| No. | Title | Solution | Difficulty | Time | Space | Topic |
|---|---|---|---|---|---|---|
| 0209 | Minimum Size Subarray Sum | Go | Medium | O(n^2) / O(n) / O(nlog n) | O(1) / O(1) / O(n) | Sliding Window |
| 0438 | Find All Anagrams in a String | Go | Medium | O(n) | O(1) | Sliding Window |
| 0567 | Permutation in String | Go | Medium | O(n) | O(1) | Sliding Window |
只要array有序, 就應該想到雙指針技巧 分為兩類 1. "快,慢指針" 2. "左,右指針"
- 快,慢指針: 主要解決 linkedlist 問題, 典型的判斷 linkedlist 是否包含環
- 左,右指針: 主要解決array(或 string)中的問題, 如二分搜尋.
https://labuladong.gitee.io/algo/2/21/57/
| No. | Title | Solution | Difficulty | Time | Space | Topic |
|---|---|---|---|---|---|---|
| 0019 | Remove Nth Node From End of List | Go | Medium | O(n) | O(1) | Linked List, Two Pointers |
| 0141 | Linked List Cycle | Go | Easy | O(n) | O(1) | Linked List, Two Pointers |
| 0283 | Move Zeroes | Go | Easy | O(n) | O(1) | Two Pointers |
| 0142 | Linked List Cycle II | Go | Medium | O(n) | O(1) | Linked List, Two Pointers |
| 0344 | Reverse String | Go | Easy | O(n) | O(1) | Two Pointers |
| 0876 | Middle of the Linked List | Go | Easy | Linked List, Two Pointers | ||
| 0074 | Search a 2D Matrix | Go | Medium | Binary Search, Two Pointers |
| No. | Title | Solution | Difficulty | Time | Space | Topic |
|---|---|---|---|---|---|---|
| 0693 | Binary Number with Alternating Bits | Go | Easy | O(n)/ O(1) | O(1) / O(1) | Bit Manipulation |
| No. | Title | Solution | Difficulty | Time | Space | Topic |
|---|---|---|---|---|---|---|
| 0721 | Accounts Merge | Go | Easy | O(n) / O(n log n) | O(n) / O(n) | Union Find |
- DFS 算法可以被認為是回溯算法, BFS算法都是用Queue這種數據結構, 每次將一個截短周圍的所有節點加入Queue.
- BFS 找到的路徑一定是最短的, 但是代價是空間複雜度比DFS大. BFS vs DFS
- 優化: 雙向 BFS 優化, 在 while 開始時做一個判斷. 讓每次都選擇較小的集合進行擴散, 那麼佔用的空間增長速度就會慢一些, 盡可能以最小的空間代價產生 curDepth 和 nextDepth 的交集 無論單向的 BFS 或是 雙向BFS, 優化過的BFS 空間複雜度都是一樣的
// 計算從起點 start 到 終點 target 的最點距離 int BFS(Node start, Node targe){ Queue<Node> q; // 核心數據結構 Set<Node> visited; // 避免走回頭路 q.offer(start); // 將起點加入 Queue visited.add(start); int step = 0; // 紀錄擴散的步數 while(q not empty) { int sz = q.size(); // 當前 Queue 中的所有節點向四周擴散 for (int i = 0 ; i < sz; i++) { Node cur = q.poll(); // 這裡判斷是否到達終點 if (cur is target) { return step; } // 將cur 的相鄰節點加入 Queue for (Node x : cur.adj()) { if (x not in visited) { q.offer(x); visited.add(x); } } } // 在這裡更新步數 step++ } }| No. | Title | Solution | Difficulty | Time | Space | Topic |
|---|---|---|---|---|---|---|
| 0310 | Minimum Height Trees | Go | Medium | Breadth First Search | ||
| 0752 | 752. Open the Lock | Go | Medium | Breadth First Search |
分析二分搜尋技巧: 不要出現 else, 而是把所有情況用 else if 寫清楚. 計算 mid 時需要防止溢出
int binarySearch(int[] nums, int target){ int left = 0 , right = ...; while(...) { int mid = left + (right - left)/2 if (nums[mid] == target){ ... } else if (nums[mid] < target){ left = ... } else if (nums[mid] > target){ right = ... } } return ...; }| No. | Title | Solution | Difficulty | Time | Space | Topic |
|---|---|---|---|---|---|---|
| 0704 | 704. Binary Search | Go | Easy | 最差:O(long n) 最佳O(1)剛好在中間 | 迭代: O(1) 遞迴O(log n) | Binary Search |
| No. | Title | Solution | Difficulty | Time | Space | Topic |
|---|---|---|---|---|---|---|
| 0226 | Invert Binary Tree | Go | Easy | O(n) | O(1) | Tree |
| 0104 | Maximum Depth of Binary Tree | Go | Easy | O(n) | O(1) | Tree |
| 0543 | Diameter of Binary Tree | Go | Easy | O(n) | O(n), O(log(n)) | Tree, DFS |
| 0110 | Balanced Binary Tree | Go | Easy | O(n) | O(1) | Tree, DFS |
| 0100 | Same Tree | Go | Easy | O(n) | O(1) | Tree |
| 0105 | Construct Binary Tree from Preorder and Inorder Traversal | Go | Medium | O(n) | O(n) | Array |
GeeksforGeeks Content
| Topic | Title | No. | Solution | Difficulty | TimeComplexity | SpaceComplexity |
|---|---|---|---|---|---|---|
| Sorting | Find Minimum Difference Between Any Two Elements | 0031 | Go | Basic | O(n^2), O(n log n) | O(n), O(n) |
Codility Content
| Topic | Title | Solution | Difficulty | TimeComplexity | SpaceComplexity | |
|---|---|---|---|---|---|---|
| Lesson 1 | Iterations | Binary Gap | Go | Painless | O(log n) | O(1) |
| Lesson 2 | Array | Cyclic Rotation | Go | Painless | O(1) | O(1) |
| Odd Occurrences In Array | Go | Painless | O(n), O(n) | O(n), O(1) | ||
| Lesson 3 | Time Complexity | Frog Jmp | Go | Painless | O(1) | O(1) |
| Perm Missing Elem | Go | Painless | O(n) | O(1) | ||
| Tape Equilibrium | Go | Painless | O(n) | O(n) | ||
| Lesson 4 | Counting Elements | Frog River One | Go | Painless | O(n) | O(n) |
| Max Counters | Go | Respectable | O(n+m) | O(n) | ||
| Missing Integer | Go | Respectable | O(n) | O(n) | ||
| Perm Check | Go | Painless | O(n) | O(n) | ||
| Lesson 5 | Prefix Sums | Count Div | Go | Respectable | O(1) | O(1) |
| Genomic Range Query | Go | Respectable | O(n+m) | O(n) | ||
| MinAvg Two Slice | Go | Respectable | O(n) | O(n) | ||
| Passing Cars | Go | Painless | O(n) | O(1) | ||
| Lesson 6 | Sorting | Distinct | Go | Painless | O(nlogn) | O(n) |
| Max Product of Three | Go | Painless | O(nlogn) | O(1) | ||
| Number Of Disc Intersections | Go | Respectable | O(nlogn) | O(n) | ||
| Triangle | Go | Painless | O(nlogn) | O(n) | ||
| Lesson 7 | Stacks and Queues | Brackets | Go | Painless | O(n) | O(n) |
| Fish | Go | Painless | O(n) | O(n) | ||
| Nesting | Go | Painless | O(n) | O(1) | ||
| Stone Wall | Go | Painless | O(n) | O(n) | ||
| Lesson 8 | Leader | Dominator | Go | Painless | O(n) | O(1) |
| EquiLeader | Go | Painless | O(n) | O(n) | ||
| Lesson 9 | Maximum slice problem | Max Profit | Go | Painless | O(n) | O(1) |
| Max Slice Sum | Go | Painless | O(n) | O(n) | ||
| Max Double Slice Sum | Go | Respectable | O(n) | O(n) | ||
| Lesson 10 | Prime and composite numbers | Count Factors | Go | Painless | O(sqrt(n)) | O(1) |
| Flags | Go | Respectable | O(n) | O(n) | ||
| MinPerimeterRectangle | Go | Painless | O(sqrt(n))) | O(1) | ||
| Peaks | Go | Respectable | O( n*log( log(n) )) | O(n) | ||
| Lesson 11 | Sieve of Eratosthenes (質數篩) | Count Non Divisible | Go | Respectable | O(N * log(N)) | O(n) |
| Count Semiprimes | Go | Respectable | O(N*log(log(N))+M) | O(N+M) | ||
| Lesson 12 | Euclidean algorithm (輾轉相除法 or 歐幾里得算法) | Chocolates By Numbers | Go | Painless | O(log(N + M)) | O(1) |
| Common Prime Divisors | Go | Respectable | O(Z * log(max(A) + max(B))**2) | O(1) | ||
| Lesson 13 | Fibonacci numbers | FibFrog | Go | Respectable | O(N * log(N)) | O(N) |
| Ladder | | Respectable | ||||
| Lesson 14 | Binary search algorithm | MinMaxDivision | | Respectable | ||
| NailingPlanks | | Respectable | ||||
| Lesson 15 | Caterpillar method | AbsDistinct | | Painless | ||
| CountDistinctSlices | | Painless | ||||
| CountTriangles | | Painless | ||||
| MinAbsSumOfTwo | | Respectable | ||||
| Lesson 16 | Greedy algorithms | MaxNonoverlappingSegments | | Painless | ||
| TieRopes | | Painless | ||||
| Lesson 17 | Dynamic programming | MinAbsSum | | Ambitious | ||
| NumberSolitaire | | Respectable | ||||