Leetcode Notes
34. Find First and Last Position of Element in Sorted Array
- 難度:medium
- 題意:給一遞增陣列,再給一數字,找出該數字們所在陣列中的開始與結束位置
- 範例:
- Input:
[5, 7, 7, 8, 8, 10], target = 8
- Output: [3, 4]
- Input:
[5, 7, 7, 8, 8, 10], target = 6
- Output: [-1, -1]
-
- Output: [-1, -1]
- 限制:
- 想法:
- 因為題目要求 O(log n),大概只剩 Binary search 可行
- Tree search methods 因為還要建樹 O(n),時間也會超過
- 程式碼
- 分析:
- 2 次的 binary search
- Time: c * log n –> 2 * log n –> O(log n)
- 解釋:
- 利用第一次 binary search 找 target 的開頭
- 利用開頭判斷條件是否符合 (數字是否存在 或 為空陣列)
- 符合後,再進入 binary search 找 target + 1 的開頭
- 此時 target + 1 的開頭 -1 就會是 target 的結尾
- NOTE:
- 一般的 binary search 不一定找得到最左邊的 target
- 因此要在條件上處理
if (arr[middle] < target) { min = middle + 1 }
else { max = middle }
- 意思就是每次找到的 target,只縮右邊一半,保證 開頭 一定會被 [min, max] 包住
- 同理,演算法也可以改成 找結尾的 binary search
53. Maximum Subarray
- 難度:medium
- 題意:給一串陣列,找出一連續子陣列,其和最大
- 範例:
- Input:
[-2, 1, -3, 4, -1, 2, 1, -5, 4]
- Output: 6
- Explanation:
[4, -1, 2, 1]
- 限制:
- 想法:
- 子陣列什麼時候到達最大值
- 當新增的數字加進來使得總和變小
[4, -1, 2, -1]
+ [-5]
–> smaller
- 如何確保子陣列增長 –> Dynamic programming
- 每次都把加到前一個數,其最大的值存起來,確保下次新增的數字使用前一次加到的最大值
- 舉例
- 加到 index 0 –> 子陣列 ==
[-2]
最大值 == -2
- 加到 index 1 –> 子陣列 ==
[-2, 1]
最大值 == 1
- 解釋: (-2 + 1) < 1,代表子陣列的頭從 1 開始往後加 比 從 -2 開始還來的大,因此可以捨去 -2
- 加到 index 2 –> 子陣列 ==
[1, -3]
最大值 == -2
- 加到 index 3 –> 子陣列 ==
[1, -3, 4]
最大值 == 4
- 解釋: (1 + -3 + 4) < 4,代表子陣列的頭從 4 開始往後加 比 從 1 + -3 開始還來的大,因此可以捨去 1, -3
- 加到 index 4 –> 子陣列 ==
[4, -1]
最大值 == 3
- 加到 index 5 –> 子陣列 ==
[4, -1, 2]
最大值 == 5
- 加到 index 6 –> 子陣列 ==
[4, -1, 2, 1]
最大值 == 6
- 加到 index 7 –> 子陣列 ==
[4, -1, 2, 1, -5]
最大值 == -1
- 加到 index 8 –> 子陣列 ==
[4, -1 ,2, 1, -5, 4]
最大值 == 3
- 程式碼
- 分析:
- time O(n) –> for loop 1 to n
- space O(1) –> constant space
- 目前沒有想到其他解法,我有看到別人使用 Kadane's algorithm,他的概念是
- 假設最大子陣列
[a, y, b]
- 則陣列
[a, y, b, x]
之最大子陣列,必為包含或不包含 [a, y, b]
之陣列,即 不可能發生 [y, b, x]
> [a, y, b, x]
69. Sqrt(x)
- 難度:easy
- 題意:給一數,求其平方根; 若有小數捨去至整數位
- 範例:
- Input:
8
- Output: 2
- Explanation:
2.82842
- 限制:
- 不能使用內建函數 pow, sqrt
- n: 1 ~ (2147483647)
- 想法:
- for 一個一個慢慢找
- Binary search
- 直立開方法
- 程式碼
70. Climbing Stairs
- 難度:easy
- 題意:給 n 階樓梯,一次走一步或兩步,問幾種方法恰好走完樓梯
- 範例:
- Input:
3
- Output: 3
- Explanation:
1 + 1 + 1
OR 1 + 2
OR 2 + 1
- 限制:
- 想法:
- 費氏數列 遞迴 (x) –> 儘量不用
- 公式解
- 建表法
- 程式碼
74. Search a 2D Matrix
- 難度:medium
- 題意:給一二維陣列,確認當中是否存某數,要求 algorithm O(log mn)
- 範例:
- Input:
[[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3
- Output: true
- 限制:
- 陣列大小: m 列 n 行
- m, n: 1 ~ 100
- matrix[i][j], target: ~
- 想法:
- 暴力解,肯定行不通,不考慮
- Binary Search
- 程式碼
- 基本上就把 matrix 攤平做 binary search 而已,沒什麼
- 搜尋過其他人解答,大部分都是 binary search,大同小異
1346. Check if N and its double exist
- 難度:easy
- 題意:給一陣列,確認當中是否存在二數,其一數為另一數的兩倍
- 範例:
- Input:
[10, 2, 5, 3]
- Output: true
- Explanation:
arr[0] = arr[2] * 2
- 限制:
- 想法:
- 暴力解,此題並無限制時間複雜度,且出現 worst case 的機率並不高(猜測)
- Binary Search,可善用 algorithm library
- Hash table (STL)
- 程式碼
其中,0 至少要出現兩次,才算存在其倍數,因此可以把 0 當 special case 處理
- 解釋 Hash table
- 第一個 for 先將,所有數字存進 map 中,相當於建一棵樹 O(n)
- 第二個 for 把每個數字遍歷,一一確認自己是否為 map 中某數的兩倍,或 map 存在其兩倍的數
- 因為 map.count 為 O(log n),因此相當於 binary search
141. Linked List Cycle
- 找 singly linked list 中是否存在 cycle
- 快慢指標? two pointers
- 如果有 cycle,fast 會在 loop 中遇到 slow,how ?

Assume time: T
Distance of Fast pointer:
Distance of slow pointer:
帶回 T 等式中
slow pointer 走完 (x - y) 個 cycle 後會遇到 fast pointer
在 的時間內,可停止循環
- 停止條件
- edge cases
- analysis
- time: 如上
- space: 只要 handle 兩個指標
- 使用 hash table 記錄所有節點,看是否出現兩次
- 用 C++ STL 較方便,以資料結構為單位,不要用 value 當作 key,因為有可能 value 會重複但沒有 cycle
- 最多 loop 次即可確定是否含 cycle
- 實作 hash table,collision 策略?
- closed addressing / chaining
- 允許 table 大小(m) 比資料筆數少,代價就是要 handle 額外空間(array / linked list) 來儲存 collision data
- best time:
- worst time:
- space:
- open addressing
- 簡單來說,就是找方法 1 to 1 mapping 進 table
- probing(linear / quadratic)
- double hashing
- space:
C++ STL
std::map
internally is a Red-Black tree.
std::unordered_map
is a Hash Table.
Find times are O(log N) vs O(1) respectively.
142. Linked List Cycle II
- 記得考慮 Initial Condition for no node or no cycle
- 方法參考 141,取
- 是 cycle 的倍數,又 k 與 一部份的 n 重疊,即
- 也就是 的中點即是 cycle 的起點(該點被兩個 next 所指到)
- 指從 cycle 起點反方向到相遇點的距離(經過 圈)
- time:
- space:
- 用 set 紀錄 visit 過的 node
- 如果找到重複的值,該值便是 cycle 起點
- time:
- space:
83. Remove Duplicates from Sorted List