用字典記錄「已見過的數 → 其索引」。遍歷時,檢查 target - n 是否在字典中,若在則直接回傳兩個索引。只需一次遍歷,時間複雜度 O(n)。
1 2 3 4 5 6 7
classSolution: deftwoSum(self, nums: List[int], target: int) -> List[int]: d = {} for j, n inenumerate(nums): if target - n in d: return [d[target - n], j] d[n] = j
classSolution: deflengthOfLongestSubstring(self, s: str) -> int: st = set() l = 0 m = 0 for r inrange(len(s)): while s[r] in st: st.remove(s[l]) l += 1 st.add(s[r]) m = max(m, r - l + 1) return m
classSolution: defmaxArea(self, height: List[int]) -> int: l, r = 0, len(height) - 1 m = 0 while l < r: i = min(height[l], height[r]) * (r - l) m = max(m, i) if height[l] <= height[r]: l += 1 else: r -= 1 return m
13. Roman to Integer
日期: 2024/12/21 | 難度: Easy | 分類: 字串、數學
題目說明
將羅馬數字字串轉換為整數。羅馬數字中若小值在大值左側,則為減法(如 IV = 4)。
解題邏輯
建立羅馬字母對應值的字典。遍歷字串,若當前值小於下一個值則減去,否則加上。
1 2 3 4 5 6 7 8 9 10 11 12 13
classSolution: defromanToInt(self, s: str) -> int: d = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000} ans = 0 for i inrange(len(s) - 1): now = d[s[i]] nex = d[s[i + 1]] if now >= nex: ans += now else: ans -= now ans += d[s[-1]] return ans
14. Longest Common Prefix
日期: 2024/12/21 | 難度: Easy | 分類: 字串
題目說明
找出字串陣列中所有字串的最長公共前綴。
解題邏輯
以第一個字串為基準,逐字元與其他字串比較,若某字元不匹配或某字串已結束,則回傳目前前綴。
1 2 3 4 5 6 7 8 9
classSolution: deflongestCommonPrefix(self, strs: List[str]) -> str: ifnot strs: return"" for i inrange(len(strs[0])): for s in strs[1:]: if i >= len(s) or s[i] != strs[0][i]: return strs[0][:i] return strs[0]
22. Generate Parentheses
日期: 2025/01/24 | 難度: Medium | 分類: 回溯、遞迴
題目說明
給 n,生成所有合法的 n 對括號組合。
解題邏輯
回溯法:追蹤已放的左括號數 open 和右括號數 close,只在 open < n 時加左括號,只在 close < open 時加右括號,長度達 2n 時加入結果。
1 2 3 4 5 6 7 8 9 10 11 12 13
classSolution: defgenerateParenthesis(self, n: int) -> List[str]: res = [] deff(s, open, close): iflen(s) == 2 * n: res.append(s) return ifopen < n: f(s + '(', open + 1, close) if close < open: f(s + ')', open, close + 1) f('', 0, 0) return res
26. Remove Duplicates from Sorted Array
日期: 2024/12/15 | 難度: Easy | 分類: 陣列、雙指針
題目說明
已排序陣列原地去除重複元素,回傳不重複元素數量 k。
解題邏輯
用 set 去重後排序,覆寫回陣列前段,回傳長度。
1 2 3 4 5 6
classSolution: defremoveDuplicates(self, nums: List[int]) -> int: l = sorted(set(nums)) for i inrange(len(l)): nums[i] = l[i] returnlen(l)
27. Remove Element
日期: 2024/12/22 | 難度: Easy | 分類: 陣列、雙指針
題目說明
原地移除陣列中所有等於 val 的元素,回傳剩餘長度。
解題邏輯
雙指針:k 追蹤下一個有效位置,遍歷時遇到非 val 元素就放到 nums[k] 並移動 k。
1 2 3 4 5 6 7 8
classSolution: defremoveElement(self, nums: List[int], val: int) -> int: k = 0 for i inrange(len(nums)): if nums[i] != val: nums[k] = nums[i] k += 1 return k
28. Find the Index of the First Occurrence in a String
classSolution: defisValidSudoku(self, board: List[List[str]]) -> bool: rows = [set() for _ inrange(9)] cols = [set() for _ inrange(9)] boxes = [set() for _ inrange(9)] for i inrange(9): for j inrange(9): val = board[i][j] if val == '.': continue box_idx = (i // 3) * 3 + j // 3 if val in rows[i] or val in cols[j] or val in boxes[box_idx]: returnFalse rows[i].add(val) cols[j].add(val) boxes[box_idx].add(val) returnTrue
classSolution: defspiralOrder(self, matrix: List[List[int]]) -> List[int]: res = [] top, bottom, left, right = 0, len(matrix) - 1, 0, len(matrix[0]) - 1 while top <= bottom and left <= right: for i inrange(left, right + 1): res.append(matrix[top][i]) top += 1 for i inrange(top, bottom + 1): res.append(matrix[i][right]) right -= 1 if top <= bottom: for i inrange(right, left - 1, -1): res.append(matrix[bottom][i]) bottom -= 1 if left <= right: for i inrange(bottom, top - 1, -1): res.append(matrix[i][left]) left += 1 return res
classSolution: defcanJump(self, nums: List[int]) -> bool: reach = 0 for i inrange(len(nums)): if i > reach: returnFalse reach = max(reach, i + nums[i]) returnTrue
classSolution: defgenerateMatrix(self, n: int) -> List[List[int]]: mat = [[0] * n for _ inrange(n)] top, bottom, left, right = 0, n - 1, 0, n - 1 num = 1 while top <= bottom and left <= right: for i inrange(left, right + 1): mat[top][i] = num; num += 1 top += 1 for i inrange(top, bottom + 1): mat[i][right] = num; num += 1 right -= 1 if top <= bottom: for i inrange(right, left - 1, -1): mat[bottom][i] = num; num += 1 bottom -= 1 if left <= right: for i inrange(bottom, top - 1, -1): mat[i][left] = num; num += 1 left += 1 return mat
classSolution: defuniquePaths(self, m: int, n: int) -> int: dp = [[1] * n for _ inrange(m)] for i inrange(1, m): for j inrange(1, n): dp[i][j] = dp[i-1][j] + dp[i][j-1] return dp[m-1][n-1]
63. Unique Paths II
日期: 2025/01/15 | 難度: Medium | 分類: 動態規劃
題目說明
同 62,但格子中有障礙物(值為 1),無法通過障礙物。
解題邏輯
同 62 的 DP,遇到障礙物則該格路徑數為 0。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
classSolution: defuniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int: m, n = len(obstacleGrid), len(obstacleGrid[0]) dp = [[0] * n for _ inrange(m)] for i inrange(m): if obstacleGrid[i][0] == 1: break dp[i][0] = 1 for j inrange(n): if obstacleGrid[0][j] == 1: break dp[0][j] = 1 for i inrange(1, m): for j inrange(1, n): if obstacleGrid[i][j] == 0: dp[i][j] = dp[i-1][j] + dp[i][j-1] return dp[m-1][n-1]
classSolution: defclimbStairs(self, n: int) -> int: to = 1 ans = t = 2 if n == 1: return1 for i inrange(3, n + 1): ans = t + to to, t = t, ans return ans
classSolution: defsetZeroes(self, matrix: List[List[int]]) -> None: l = [] lst = [list(i) for i inzip(*matrix)] for i inrange(len(matrix)): if matrix[i].count(0) == 0: n = [] for j inrange(len(matrix[i])): if lst[j].count(0) == 0: n.append(matrix[i][j]) else: n.append(0) l.append(n) else: l.append([0] * len(matrix[i])) matrix[:] = l[:]
classSolution: defisSymmetric(self, root): ifnot root: returnTrue q = [root] while q: n = len(q) l = [] for i inrange(n): r = q.pop(0) if r: l.append(r.val) q.append(r.left) q.append(r.right) else: l.append(None) if l != l[::-1]: returnFalse returnTrue
102. Binary Tree Level Order Traversal
日期: 2025/01/14 | 難度: Medium | 分類: 樹、BFS
題目說明
回傳二元樹的逐層遍歷結果(每層為一個列表)。
解題邏輯
BFS:用 queue 進行層序遍歷,每次處理同一層的所有節點並加入 level 列表。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
classSolution: deflevelOrder(self, root): ifnot root: return [] q = [root] l = [] while q: level = [] for i inrange(len(q)): node = q.pop(0) level.append(node.val) if node.left: q.append(node.left) if node.right: q.append(node.right) l.append(level) return l
classSolution: defgenerate(self, numRows: int) -> List[List[int]]: c = [[1] * (i + 1) for i inrange(numRows)] for i inrange(2, numRows): for j inrange(1, i): c[i][j] = c[i - 1][j - 1] + c[i - 1][j] return c
classSolution: defgetRow(self, rowIndex: int) -> list[int]: row = [1] for i inrange(rowIndex): row.append(0) for j inrange(len(row) - 1, 0, -1): row[j] += row[j - 1] return row
121. Best Time to Buy and Sell Stock
日期: 2024/12/16 | 難度: Easy | 分類: 貪心、動態規劃
題目說明
只能買賣一次,求最大利潤。
解題邏輯
一次遍歷:維護最低買入價 mn 和最大利潤 dp,每天更新兩者。
1 2 3 4 5 6 7 8
classSolution: defmaxProfit(self, prices: List[int]) -> int: dp = float(-inf) mn = float(inf) for i in prices: mn = min(i, mn) dp = max(dp, i - mn) return dp
122. Best Time to Buy and Sell Stock II
日期: 2025/01/15 | 難度: Medium | 分類: 貪心
題目說明
可以多次買賣,但同一時間只能持有一股,求最大利潤。
解題邏輯
貪心:只要今天比昨天高,就把差價(利潤)加進來。等同於在每個上升段都賺到差價。
1 2 3 4 5 6 7 8 9
classSolution: defmaxProfit(self, prices: List[int]) -> int: io = prices[0] n = 0 for i in prices[1:]: if i > io: n += i - io io = i return n
136. Single Number
日期: 2024/12/17 | 難度: Easy | 分類: 位元運算
題目說明
每個元素出現兩次,只有一個出現一次,找出它。
解題邏輯
XOR:相同的數 XOR 為 0,所有數 XOR 後剩下的就是只出現一次的數。
1 2 3 4 5 6
classSolution: defsingleNumber(self, nums: List[int]) -> int: x = 0 for i in nums: x ^= i return x
137. Single Number II
日期: 2024/12/17 | 難度: Medium | 分類: 位元運算
題目說明
每個元素出現三次,只有一個出現一次,用 O(1) 空間找出它。
解題邏輯
用兩個位元遮罩 x、y 模擬三進制計數,出現三次的數會被清零,剩下 x 就是答案。
1 2 3 4 5 6 7
classSolution: defsingleNumber(self, nums: List[int]) -> int: x = y = 0 for i in nums: x = x ^ i & ~y y = y ^ i & ~x return x
150. Evaluate Reverse Polish Notation
日期: 2024/12/18 | 難度: Medium | 分類: Stack
題目說明
計算逆波蘭表達式(後綴表達式)。
解題邏輯
Stack:遇數字 push;遇運算子 pop 兩個數計算後 push 結果。
1 2 3 4 5 6 7 8 9 10 11
classSolution: defevalRPN(self, tokens: List[str]) -> int: l = [] for i in tokens: if i in ['+', '-', '*', '/']: b = l.pop() a = l.pop() l.append(int(eval(str(a) + i + str(b)))) else: l.append(int(i)) returnint(l[0])
classSolution: defrob(self, nums: List[int]) -> int: prev2 = prev1 = 0 for n in nums: prev2, prev1 = prev1, max(prev1, prev2 + n) return prev1
202. Happy Number
日期: 2024/12/23 | 難度: Easy | 分類: 數學、雜湊集合
題目說明
對一個數,反覆將各位數字的平方和替換,最終若能到 1 則為「快樂數」。
解題邏輯
用集合記錄見過的數,若重複出現代表進入循環(不是快樂數),若到 1 則是。
1 2 3 4 5 6 7 8 9
classSolution: defisHappy(self, n: int) -> bool: seen = set() while n != 1: if n in seen: returnFalse seen.add(n) n = sum(int(d) ** 2for d instr(n)) returnTrue
205. Isomorphic Strings
日期: 2024/12/24 | 難度: Easy | 分類: 字串、雜湊表
題目說明
判斷兩個字串是否同構(可以通過一對一的字元映射使 s 變成 t)。
解題邏輯
建立兩個方向的映射字典,確保 s→t 和 t→s 的映射都是一對一的。
1 2 3 4 5 6 7 8 9
classSolution: defisIsomorphic(self, s: str, t: str) -> bool: d1, d2 = {}, {} for a, b inzip(s, t): if d1.get(a, b) != b or d2.get(b, a) != a: returnFalse d1[a] = b d2[b] = a returnTrue
209. Minimum Size Subarray Sum
日期: 2025/01/21 | 難度: Medium | 分類: 滑動視窗
題目說明
找和 ≥ target 的最短連續子陣列長度。
解題邏輯
滑動視窗:右指針 i 擴張累加,當 s >= target 時記錄長度並從左收縮,持續更新最小長度。
1 2 3 4 5 6 7 8 9 10 11 12
classSolution: defminSubArrayLen(self, target: int, nums: List[int]) -> int: j = 0 s = 0 min_len = float('inf') for i inrange(len(nums)): s += nums[i] while s >= target: min_len = min(min_len, i - j + 1) s -= nums[j] j += 1 return0if min_len == float('inf') else min_len
213. House Robber II
日期: 2024/12/25 | 難度: Medium | 分類: 動態規劃
題目說明
房子排成環狀(首尾相鄰),不能搶相鄰房子,求最大金額。
解題邏輯
環狀問題拆成兩個線性問題:搶 nums[0..n-2] 或搶 nums[1..n-1],取兩者最大值。每個子問題用 House Robber I 的 DP 解。
classSolution: defcombinationSum3(self, k: int, n: int) -> List[List[int]]: res = [] deff(start, path, remain): iflen(path) == k and remain == 0: res.append(path[:]) return for i inrange(start, 10): if i > remain: break path.append(i) f(i + 1, path, remain - i) path.pop() f(1, [], n) return res
219. Contains Duplicate II
日期: 2024/12/27 | 難度: Easy | 分類: 雜湊表、滑動視窗
題目說明
判斷陣列中是否存在兩個相同的數,且它們的索引差 ≤ k。
解題邏輯
用字典記錄每個數最後出現的索引,若同一個數再次出現且索引差 ≤ k 則回傳 True。
1 2 3 4 5 6 7 8
classSolution: defcontainsNearbyDuplicate(self, nums: List[int], k: int) -> bool: d = {} for i, n inenumerate(nums): if n in d and i - d[n] <= k: returnTrue d[n] = i returnFalse
classSolution: defcalculate(self, s: str) -> int: sign = 1 stack = [sign] num = 0 res = 0 s += ' ' for i in s: if i.isdigit(): num = 10 * num + int(i) else: res += sign * num num = 0 if i == '+': sign = stack[-1] elif i == '-': sign = -stack[-1] elif i == '(': stack.append(sign) elif i == ')': stack.pop() return res
classSolution: defcalculate(self, s: str) -> int: l = [] n = '' t = '+' s += '+' for i in s: if i == " ": continue if i.isdigit(): n += i else: n = int(n) if t == "+": l.append(n) elif t == "-": l.append(-n) elif t == "*": l.append(l.pop() * n) elif t == "/": l.append(int(l.pop() / n)) t = i n = '' returnsum(l)
classSolution: defsearchMatrix(self, matrix, target): r, c = 0, len(matrix[0]) - 1 while r < len(matrix) and c >= 0: if matrix[r][c] == target: returnTrue elif matrix[r][c] > target: c -= 1 else: r += 1 returnFalse
classSolution: defisUgly(self, n: int) -> bool: if n <= 0: returnFalse for p in [2, 3, 5]: while n % p == 0: n //= p return n == 1
283. Move Zeroes
日期: 2024/12/16 | 難度: Easy | 分類: 陣列
題目說明
原地將所有 0 移到末尾,保持非零元素相對順序。
解題邏輯
計算 0 的個數,反覆執行「移除第一個 0 → 末尾補 0」。
1 2 3 4 5 6
classSolution: defmoveZeroes(self, nums: List[int]) -> None: c = nums.count(0) for i inrange(c): nums.remove(0) nums.append(0)
290. Word Pattern
日期: 2024/12/28 | 難度: Easy | 分類: 字串、雜湊表
題目說明
判斷 pattern 和 s 是否遵循相同的模式(字母對單字,一對一映射)。
解題邏輯
建立雙向映射(字母→單字、單字→字母),確保兩側都是一對一。
1 2 3 4 5 6 7 8 9 10 11 12
classSolution: defwordPattern(self, pattern: str, s: str) -> bool: words = s.split() iflen(pattern) != len(words): returnFalse d1, d2 = {}, {} for p, w inzip(pattern, words): if d1.get(p, w) != w or d2.get(w, p) != p: returnFalse d1[p] = w d2[w] = p returnTrue
300. Longest Increasing Subsequence
日期: 2025/01/05 | 難度: Medium | 分類: 動態規劃
題目說明
找出最長嚴格遞增子序列的長度。
解題邏輯
DP:dp[i] = 以 nums[i] 結尾的最長遞增子序列長度,對每個 i 往前找所有 j < i 且 nums[j] < nums[i] 的 dp[j]+1 取最大。
1 2 3 4 5 6 7 8
classSolution: deflengthOfLIS(self, nums: List[int]) -> int: dp = [1] * len(nums) for i inrange(1, len(nums)): for j inrange(i): if nums[j] < nums[i]: dp[i] = max(dp[i], dp[j] + 1) returnmax(dp)
322. Coin Change
日期: 2025/01/24 | 難度: Medium | 分類: 動態規劃
題目說明
給硬幣面額陣列和目標金額,求湊成 amount 所需的最少硬幣數,無法湊成回傳 -1。
解題邏輯
Bottom-up DP:dp[i] = 湊成金額 i 的最少硬幣數。對每個金額,嘗試所有硬幣,dp[i] = min(dp[i], dp[i-c]+1)。
1 2 3 4 5 6 7 8 9
classSolution: defcoinChange(self, coins: List[int], amount: int) -> int: dp = [float('inf')] * (amount + 1) dp[0] = 0 for i inrange(1, amount + 1): for c in coins: if c <= i: dp[i] = min(dp[i], dp[i - c] + 1) return dp[amount] if dp[amount] != float('inf') else -1
334. Increasing Triplet Subsequence
日期: 2025/02/03 | 難度: Medium | 分類: 貪心
題目說明
判斷是否存在長度為 3 的遞增子序列。
解題邏輯
貪心:維護兩個變數 first(最小值)和 second(在 first 之後的次小值),若遇到比 second 大的數則找到三元組。
1 2 3 4 5 6 7 8 9 10 11
classSolution: defincreasingTriplet(self, nums: List[int]) -> bool: first = second = float('inf') for n in nums: if n <= first: first = n elif n <= second: second = n else: returnTrue returnFalse
338. Counting Bits
日期: 2025/01/02 | 難度: Easy | 分類: 動態規劃、位元運算
題目說明
給 n,回傳 0 到 n 每個數的二進位表示中 1 的個數。
解題邏輯
DP:dp[i] = dp[i >> 1] + (i & 1)(右移一位去掉最低位,加上最低位是否為 1)。
1 2 3 4 5 6
classSolution: defcountBits(self, n: int) -> List[int]: dp = [0] * (n + 1) for i inrange(1, n + 1): dp[i] = dp[i >> 1] + (i & 1) return dp
classSolution: defreverseVowels(self, s: str) -> str: vowels = set('aeiouAEIOU') s = list(s) l, r = 0, len(s) - 1 while l < r: while l < r and s[l] notin vowels: l += 1 while l < r and s[r] notin vowels: r -= 1 s[l], s[r] = s[r], s[l] l += 1; r -= 1 return''.join(s)
350. Intersection of Two Arrays II
日期: 2024/12/15 | 難度: Easy | 分類: 雜湊表
題目說明
找兩個陣列的交集(含重複元素),每個元素出現次數取兩者最小值。
解題邏輯
找共同元素集合,每個元素按 min(count1, count2) 次加入結果。
1 2 3 4 5 6 7 8 9 10 11 12
classSolution: defintersect(self, nums1, nums2): s = set() for i in nums1: if i in nums2: s.add(i) l = [] for i in s: c = min(nums1.count(i), nums2.count(i)) for j inrange(c): l.append(i) return l
classSolution: defgetSum(self, a: int, b: int) -> int: mask = 0xFFFFFFFF while b & mask: carry = (a & b) << 1 a = a ^ b b = carry return (a & mask) if b > 0else a
classSolution: defcanConstruct(self, ransomNote: str, magazine: str) -> bool: d = Counter(magazine) for c in ransomNote: if d[c] <= 0: returnFalse d[c] -= 1 returnTrue
387. First Unique Character in a String
日期: 2024/12/23 | 難度: Easy | 分類: 字串、雜湊表
題目說明
找字串中第一個不重複字元的索引,不存在回傳 -1。
解題邏輯
Counter 統計頻次,再遍歷找第一個頻次為 1 的字元。
1 2 3 4 5 6 7
classSolution: deffirstUniqChar(self, s: str) -> int: d = Counter(s) for i, c inenumerate(s): if d[c] == 1: return i return -1
389. Find the Difference
日期: 2024/12/17 | 難度: Easy | 分類: 字串、位元運算
題目說明
字串 t 是 s 打亂後多插入一個字母,找出多出的那個字母。
解題邏輯
將 t 所有字母的 ASCII 碼加總,減去 s 所有字母的 ASCII 碼,差值即為多出字母的 ASCII。
1 2 3 4 5 6 7 8
classSolution: deffindTheDifference(self, s: str, t: str) -> str: ans = 0 for i in t: ans += ord(i) for i in s: ans -= ord(i) returnchr(ans)
392. Is Subsequence
日期: 2025/02/05 | 難度: Easy | 分類: 雙指針、字串
題目說明
判斷 s 是否為 t 的子序列(保持相對順序但不一定連續)。
解題邏輯
雙指針:i 指向 s,j 指向 t,遍歷 t,遇到 s[i] 時 i 前進,最終若 i == len(s) 則是子序列。
1 2 3 4 5 6 7
classSolution: defisSubsequence(self, s: str, t: str) -> bool: i = 0 for c in t: if i < len(s) and c == s[i]: i += 1 return i == len(s)
classSolution: deftoHex(self, num: int) -> str: if num == 0: return'0' hex_chars = '0123456789abcdef' res = '' if num < 0: num = num + 2**32 while num: res = hex_chars[num & 0xf] + res num >>= 4 return res
classSolution: deflongestPalindrome(self, s: str) -> int: d = Counter(s) res = 0 odd = False for v in d.values(): res += v if v % 2 == 0else v - 1 if v % 2 == 1: odd = True return res + (1if odd else0)
435. Non-overlapping Intervals
日期: 2025/01/05 | 難度: Medium | 分類: 貪心、排序
題目說明
找最少需要移除幾個區間才能使剩餘區間互不重疊。
解題邏輯
貪心:按結束時間排序,盡量保留結束時間早的區間(貪心選擇),遇到重疊就計數移除。
1 2 3 4 5 6 7 8 9 10 11
classSolution: deferaseOverlapIntervals(self, intervals: List[List[int]]) -> int: intervals.sort(key=lambda x: x[1]) count = 0 end = float('-inf') for s, e in intervals: if s >= end: end = e else: count += 1 return count
classSolution: defcompress(self, chars: List[str]) -> int: w = 0 i = 0 while i < len(chars): c = chars[i] count = 0 while i < len(chars) and chars[i] == c: i += 1 count += 1 chars[w] = c w += 1 if count > 1: for d instr(count): chars[w] = d w += 1 return w
classSolution: deffindDisappearedNumbers(self, nums: List[int]) -> List[int]: for n in nums: i = abs(n) - 1 nums[i] = -abs(nums[i]) return [i + 1for i inrange(len(nums)) if nums[i] > 0]
463. Island Perimeter
日期: 2024/12/28 | 難度: Easy | 分類: 陣列、矩陣
題目說明
給一個格狀地圖,1 代表陸地,0 代表水,計算島嶼的周長。
解題邏輯
每個陸地格貢獻 4 條邊,但相鄰的陸地格共享的邊不算,每對相鄰陸地減 2。
1 2 3 4 5 6 7 8 9 10 11 12
classSolution: defislandPerimeter(self, grid: List[List[int]]) -> int: res = 0 for i inrange(len(grid)): for j inrange(len(grid[0])): if grid[i][j] == 1: res += 4 if i > 0and grid[i-1][j] == 1: res -= 2 if j > 0and grid[i][j-1] == 1: res -= 2 return res
classSolution: defnextGreaterElement(self, nums1, nums2): d = {} stack = [] for n in nums2: while stack and stack[-1] < n: d[stack.pop()] = n stack.append(n) return [d.get(n, -1) for n in nums1]
500. Keyboard Row
日期: 2024/12/27 | 難度: Easy | 分類: 字串、雜湊表
題目說明
找出陣列中能用鍵盤同一行字母拼寫的單字。
解題邏輯
定義三行的字母集合,判斷每個單字的字母是否全在同一行中。
1 2 3 4 5 6 7 8 9
classSolution: deffindWords(self, words: List[str]) -> List[str]: rows = [set('qwertyuiop'), set('asdfghjkl'), set('zxcvbnm')] res = [] for w in words: s = set(w.lower()) ifany(s <= r for r in rows): res.append(w) return res
543. Diameter of Binary Tree
日期: 2025/01/13 | 難度: Easy | 分類: 樹、遞迴
題目說明
求二元樹的直徑(任意兩節點間最長路徑的邊數)。
解題邏輯
DFS:每個節點的直徑候選 = 左子樹深度 + 右子樹深度,遞迴過程中更新全域最大值。
1 2 3 4 5 6 7 8 9 10 11 12
classSolution: defdiameterOfBinaryTree(self, root): self.ans = 0 defdepth(node): ifnot node: return0 l = depth(node.left) r = depth(node.right) self.ans = max(self.ans, l + r) returnmax(l, r) + 1 depth(root) returnself.ans
556. Next Greater Element III
日期: 2024/12/28 | 難度: Medium | 分類: 數學、字串
題目說明
給一個整數 n,找出用 n 的各位數字重排後比 n 大的最小整數,不存在或超出 32 位範圍則回傳 -1。
解題邏輯
Next permutation 演算法:從右找第一個下降點 i,再從右找第一個比 digits[i] 大的數交換,最後反轉 i+1 之後的部分。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
classSolution: defnextGreaterElement(self, n: int) -> int: digits = list(str(n)) i = len(digits) - 2 while i >= 0and digits[i] >= digits[i + 1]: i -= 1 if i < 0: return -1 j = len(digits) - 1 while digits[j] <= digits[i]: j -= 1 digits[i], digits[j] = digits[j], digits[i] digits[i + 1:] = digits[i + 1:][::-1] res = int(''.join(digits)) return res if res <= 2**31 - 1else -1
classSolution: deffindUnsortedSubarray(self, nums: List[int]) -> int: sorted_nums = sorted(nums) l, r = 0, len(nums) - 1 while l <= r and nums[l] == sorted_nums[l]: l += 1 while r >= l and nums[r] == sorted_nums[r]: r -= 1 return r - l + 1if l <= r else0
637. Average of Levels in Binary Tree
日期: 2025/01/13 | 難度: Easy | 分類: 樹、BFS
題目說明
回傳二元樹每層節點的平均值。
解題邏輯
BFS 層序遍歷,每層計算平均值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
classSolution: defaverageOfLevels(self, root): res = [] q = [root] while q: level = [] for _ inrange(len(q)): node = q.pop(0) level.append(node.val) if node.left: q.append(node.left) if node.right: q.append(node.right) res.append(sum(level) / len(level)) return res
643. Maximum Average Subarray I
日期: 2025/02/05 | 難度: Easy | 分類: 滑動視窗
題目說明
找長度為 k 的連續子陣列的最大平均值。
解題邏輯
固定大小的滑動視窗:先計算前 k 個元素的和,然後逐步移動視窗(加新去舊),維護最大和。
1 2 3 4 5 6 7 8
classSolution: deffindMaxAverage(self, nums: List[int], k: int) -> float: w = sum(nums[:k]) m = w for i inrange(k, len(nums)): w += nums[i] - nums[i - k] m = max(m, w) return m / k
704. Binary Search
日期: 2024/12/20 | 難度: Easy | 分類: 二分搜尋
題目說明
在已排序陣列中找目標值的索引,找不到回傳 -1。
解題邏輯
標準二分搜尋:維護左右邊界,每次取中點比較縮小範圍。
1 2 3 4 5 6 7 8 9 10 11 12 13
classSolution: defsearch(self, nums: List[int], target: int) -> int: r = len(nums) - 1 left = 0 while r >= left: mid = (r + left) // 2 if nums[mid] < target: left = mid + 1 elif nums[mid] > target: r = mid - 1 else: return mid return -1
724. Find Pivot Index
日期: 2024/12/20 | 難度: Easy | 分類: 前綴和
題目說明
找樞紐索引:左側所有元素之和等於右側所有元素之和。
解題邏輯
n 從總和開始每次扣當前元素(= 右側和),s 累積(= 左側和),相等時找到樞紐。
1 2 3 4 5 6 7 8 9 10
classSolution: defpivotIndex(self, nums: List[int]) -> int: n = sum(nums) s = 0 for c, i inenumerate(nums): n -= i if s == n: return c s += i return -1
772. Basic Calculator III
日期: 2024/12/18 | 難度: Hard | 分類: Stack、Shunting Yard
題目說明
實作完整計算機,支援 +、-、*、/ 及括號(224 + 227 的合體)。
解題邏輯
Shunting Yard 演算法:中綴轉 RPN 再計算。負號在開頭或括號後補 0-,利用優先級字典 d 控制運算子 pop 時機。
classSolution: defcalculate(self, s: str) -> int: stack = [] tokens = [] d = {'+': 1, '-': 1, '*': 2, '/': 2} s1 = '' num = '' for i inrange(len(s)): if s[i] == ' ': continue s1 += s[i] s = '' for i inrange(len(s1)): if s1[i] == "-"and (i == 0or s1[i-1] == "("): s += "0-" else: s += s1[i] i = 0 while i < len(s): if s[i].isdigit(): while i < len(s) and s[i].isdigit(): num += s[i] i += 1 tokens.append(int(num)) i -= 1 num = '' elif s[i] == "(": stack.append(s[i]) elif s[i] == ')': while stack and stack[-1] != '(': tokens.append(stack.pop()) stack.pop() else: while stack and d.get(stack[-1], 0) >= d.get(s[i]): tokens.append(stack.pop()) stack.append(s[i]) i += 1 while stack: tokens.append(stack.pop()) l = [] for i in tokens: if i in ['+', '-', '*', '/']: a = l.pop() b = l.pop() if i == '+': l.append(b + a) elif i == '-': l.append(b - a) elif i == '*': l.append(b * a) elif i == '/': l.append(int(b / a)) else: l.append(int(i)) return l[0]
二分搜尋答案範圍 [1, max(piles)]:對每個速度 mid,計算需要的小時數,若超過 h 則加速(left 右移),否則嘗試更慢(right 左移)。
1 2 3 4 5 6 7 8 9 10 11 12
classSolution: defminEatingSpeed(self, piles, h) -> int: from math import ceil left = 1 right = max(piles) while left <= right: mid = (left + right) // 2 ifsum(ceil(p / mid) for p in piles) > h: left = mid + 1 else: right = mid - 1 return left
1004. Max Consecutive Ones III
日期: 2025/02/18 | 難度: Medium | 分類: 滑動視窗
題目說明
最多可以翻轉 k 個 0,找最長的全 1 子陣列。
解題邏輯
滑動視窗:c 計算視窗內 0 的個數,超過 k 時從左收縮(若移除的是 0 則 c–),持續更新最大視窗長度。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
classSolution: deflongestOnes(self, nums: List[int], k: int) -> int: c = 0 io = 0 m = 0 for i inrange(len(nums)): if nums[i] == 0: c += 1 while c > k: if nums[io] == 0: c -= 1 io += 1 if i - io + 1 > m: m = i - io + 1 return m
1008. Construct Binary Search Tree from Preorder Traversal
日期: 2025/02/18 | 難度: Medium | 分類: 樹、BST
題目說明
給一個 BST 的前序遍歷陣列,重建該 BST。
解題邏輯
遞迴插入:對每個新值,從根開始比較,大於當前節點往右插,小於往左插。依序從前序陣列取值插入即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
classSolution: defbstFromPreorder(self, preorder: List[int]): deff(node, v): ifnot node: return TreeNode(v) if node.val < v: node.right = f(node.right, v) else: node.left = f(node.left, v) return node ifnot preorder: return TreeNode() tree = TreeNode(preorder.pop(0)) while preorder: f(tree, preorder.pop(0)) return tree
1207. Unique Number of Occurrences
日期: 2025/02/19 | 難度: Easy | 分類: 雜湊表
題目說明
判斷陣列中每個值的出現次數是否各不相同。
解題邏輯
Counter 取得各值頻次,比較頻次列表的長度和頻次集合的長度,相等則各不相同。
1 2 3 4 5
classSolution: defuniqueOccurrences(self, arr: List[int]) -> bool: d = Counter(arr) l = list(d.values()) returnlen(l) == len(set(l))
1295. Find Numbers with Even Number of Digits
日期: 2024/12/20 | 難度: Easy | 分類: 陣列
題目說明
找出陣列中位數為偶數的整數個數。
解題邏輯
轉字串取長度,篩選偶數長度的計數。
1 2 3
classSolution: deffindNumbers(self, nums: List[int]) -> int: returnsum(1for i in nums iflen(str(i)) % 2 == 0)
1365. How Many Numbers Are Smaller Than the Current Number
日期: 2024/12/21 | 難度: Easy | 分類: 排序、計數排序
題目說明
對每個元素計算有多少其他元素比它小。
解題邏輯 — 方法一(計數排序)
長度 101 的計數陣列,前綴和即為比當前值小的元素個數。
解題邏輯 — 方法二(排序 + index)
排序後每個元素第一次出現的索引即為答案。
1 2 3 4 5 6 7 8 9 10 11 12 13
# 方法一 classSolution: defsmallerNumbersThanCurrent(self, nums): dic = [0] * 101 for i in nums: dic[i] += 1 return [sum(dic[0:i]) for i in nums]
# 方法二 classSolution: defsmallerNumbersThanCurrent(self, nums): tmp = sorted(nums) return [tmp.index(i) for i in nums]
classSolution: deflongestZigZag(self, root): self.ans = 0 defdfs(node, left, right): self.ans = max(self.ans, left, right) if node.left: dfs(node.left, 0, left + 1) if node.right: dfs(node.right, right + 1, 0) if root: dfs(root, 0, 0) returnself.ans
1448. Count Good Nodes in Binary Tree
日期: 2025/02/24 | 難度: Medium | 分類: 樹、DFS
題目說明
「好節點」定義為從根到該節點的路徑上,沒有比它更大的節點。計算樹中好節點的數量。
解題邏輯
DFS 傳遞路徑上的最大值,每個節點若 ≥ 路徑最大值則為好節點,計數加 1。
1 2 3 4 5 6 7 8 9 10 11
classSolution: defgoodNodes(self, root): defdfs(node, max_val): ifnot node: return0 res = 1if node.val >= max_val else0 max_val = max(max_val, node.val) res += dfs(node.left, max_val) res += dfs(node.right, max_val) return res return dfs(root, float('-inf'))
1456. Maximum Number of Vowels in a Substring of Given Length
日期: 2025/02/18 | 難度: Medium | 分類: 滑動視窗
題目說明
給字串 s 和整數 k,找長度為 k 的子字串中母音字母的最多個數。
解題邏輯
固定大小滑動視窗:先計算前 k 個字元的母音數,再移動視窗加新去舊,更新最大值。
1 2 3 4 5 6 7 8 9
classSolution: defmaxVowels(self, s: str, k: int) -> int: vowels = set('aeiou') w = sum(1for c in s[:k] if c in vowels) m = w for i inrange(k, len(s)): w += (s[i] in vowels) - (s[i - k] in vowels) m = max(m, w) return m
classSolution: defmaxOperations(self, nums: List[int], k: int) -> int: d = Counter(nums) res = 0 for n inlist(d.keys()): complement = k - n if complement in d: if n == complement: res += d[n] // 2 d[n] = 0 else: pairs = min(d[n], d[complement]) res += pairs d[n] -= pairs d[complement] -= pairs return res
1748. Sum of Unique Elements
日期: 2024/12/20 | 難度: Easy | 分類: 雜湊表
題目說明
回傳陣列中只出現一次的元素的總和。
解題邏輯
Counter 篩選出現次數為 1 的元素加總。
1 2 3
classSolution: defsumOfUnique(self, nums: List[int]) -> int: returnsum(a for a, b in Counter(nums).items() if b == 1)
classSolution: defmergeAlternately(self, word1: str, word2: str) -> str: res = '' for a, b inzip(word1, word2): res += a + b iflen(word1) > len(word2): res += word1[len(word2):] else: res += word2[len(word1):] return res
2114. Maximum Number of Words Found in Sentences
日期: 2024/12/20 | 難度: Easy | 分類: 字串
題目說明
找句子陣列中單字數最多的句子,回傳最大單字數。
解題邏輯
對每個句子 split() 後取長度,找最大值。
1 2 3
classSolution: defmostWordsFound(self, sentences: List[str]) -> int: returnmax([len(i.split()) for i in sentences])
classSolution: defbuttonWithLongestTime(self, events): d = {} io = 0 for a, b in events: t = b - io if a in d: if d[a] < t: d[a] = t else: d[a] = t io = b m = max(d.values()) returnmin([i for i, b in d.items() if b == m])
k=int(input()) s=input() a=[1if i.isupper() else -1for i in s] res=0 for i inrange(len(a)): ix=i+k j=0#0>k 1>0 whileTrue: if j==1: ifsum(a[i:ix])==0: ix+=k j=0 else: if ix-i>res: res=ix-i-k break elif j==0: if a[i]==1andsum(a[i:ix])==k: ix+=k j=1 elif a[i]==-1andsum(a[i:ix]) ==-k: ix+=k j=1 else: if ix-i>res: res=ix-i-k break if ix>len(a): if ix-i>res: res=ix-i-k break print(res)
for i inrange(len(l[-1]) - 1, -1, -1): if l[-1][i] == '1': c += 1 sl.append(s[i]) else: sl.insert(0, s[i])
ins = "" if c % 2 == 0: ins = ''.join(sl) else: iflen(s) % 2 == 0: mid = len(s) // 2 ins = ''.join(sl[mid:]) + ''.join(sl[:mid]) else: mid = len(s) // 2 ins = ''.join(sl[mid + 1:]) + sl[mid] + ''.join(sl[:mid])
s = ins l.pop()
print(s)
m931. 遊戲選角
日期: 2024/1 | 難度: Easy | 分類: 排序 / 模擬
1 2 3 4 5 6 7 8
n=int(input()) l=[list(map(int,input().split()))for i inrange(n)] d={} for i inrange(n): ans=l[i][0]**2+l[i][1]**2 d[i]=ans k=sorted(d,key=d.get,reverse=True) print(*l[k[1]])
a,b,c=map(int,input().split()) l=[[i for i ininput()]for i inrange(a)] nums=list(map(int,input().split())) s='' y=a-1 x=0 for i in nums: if i==0: if y!=0: y-=1 if i==1: if x!=(b-1): x+=1 if i==2: if x!=(b-1) and y!=(a-1): y+=1 x+=1 if i==3: if y!=(a-1): y+=1 if i==4: if x!=0: x-=1 if i==5: if y!=0and x!=0: x-=1 y-=1 s+=l[y][x] print(s)
M, N, k, r, c = map(int, input().split()) l = [list(map(int, input().split())) for i inrange(M)] s = 0 f = 0 b = 0
while l[r][c] != 0: t = 1 s += l[r][c] b += 1 l[r][c] -= 1 if s % k == 0: f += 1 f %= 4 while t == 1: if f == 0and c + 1 < N: if l[r][c + 1] != -1: c += 1 t = 0 else: f += 1 f %= 4 elif f == 1and r + 1 < M: if l[r + 1][c] != -1: r += 1 t = 0 else: f += 1 f %= 4 elif f == 2and c - 1 >= 0: if l[r][c - 1] != -1: c -= 1 t = 0 else: f += 1 f %= 4 elif f == 3and r - 1 >= 0: if l[r - 1][c] != -1: r -= 1 t = 0 else: f += 1 f %= 4 else: f+=1 f %= 4
print(b)
q836. 小心陷阱
日期: 2025/6 | 難度: Easy | 分類: 模擬
1 2 3 4 5 6 7 8 9 10 11
k=int(input()) x1,y1=map(int,input().split()) x2,y2=map(int,input().split()) p=0 while k>0: p+=k if p%x1==0: k-=y1 if p%x2==0: k-=y2 print(p)
q837. 轉盤得分
日期: 2025/6 | 難度: Medium | 分類: 模擬 / 陣列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
m,n,k=map(int,input().split()) l=[input()for i inrange(m)] t=[]
ans=0 for values in [list(map(int, input().split()))for _ inrange(k)]:
for i inrange(m): s = l[i] p = values[i] % n s = s[-p:] + s[:-p] l[i] = s for i inzip(*l): ans+=max(i.count(j)for j in i) print(ans)
q838. 貪心闖關
日期: 2025/6 | 難度: Medium | 分類: 貪心 / 堆疊
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
n, t = map(int, input().split()) st = [] ans = 0 l = list(map(int, input().split())) for i inrange(n): x = l[i] while st and st[-1] <= x: ans += st[-1] x += st[-1] st.pop() if x <= t: st.append(x) for x in st: ans += x print(ans)