以下是五大核心算法的重點解析和LeetCode經典題解,包含最優解法和模板代碼:
一、數組操作(雙指針/滑動窗口)
核心思想:通過索引指針高效遍歷與操作數組
1. 移動零(No.283)
def moveZeroes(nums):slow = 0for fast in range(len(nums)):if nums[fast] != 0:nums[slow], nums[fast] = nums[fast], nums[slow]slow += 1
2. 盛最多水的容器(No.11)
def maxArea(height):left, right = 0, len(height)-1max_area = 0while left < right:area = min(height[left], height[right]) * (right - left)max_area = max(max_area, area)if height[left] < height[right]:left += 1else:right -= 1return max_area
3. 最小覆蓋子串(No.76)滑動窗口模板
def minWindow(s, t):from collections import Counterneed = Counter(t)missing = len(t)left = start = end = 0for right, char in enumerate(s, 1):if need[char] > 0:missing -= 1need[char] -= 1if missing == 0: # 窗口滿足條件# 收縮左邊界while left < right and need[s[left]] < 0:need[s[left]] += 1left += 1# 更新結果if not end or right-left <= end-start:start, end = left, right# 移動左邊界need[s[left]] += 1missing += 1left += 1return s[start:end]
二、哈希表應用(快速查找)
核心思想:空間換時間,實現O(1)查找
1. 兩數之和(No.1)
def twoSum(nums, target):seen = {}for i, num in enumerate(nums):if target - num in seen:return [seen[target-num], i]seen[num] = ireturn []
2. 字母異位詞分組(No.49)
def groupAnagrams(strs):from collections import defaultdictd = defaultdict(list)for s in strs:key = ''.join(sorted(s))d[key].append(s)return list(d.values())
3. 最長連續序列(No.128)
def longestConsecutive(nums):num_set = set(nums)max_len = 0for num in num_set:# 確保從序列起點開始if num-1 not in num_set:curr = numcurr_len = 1while curr+1 in num_set:curr += 1curr_len += 1max_len = max(max_len, curr_len)return max_len
三、樹形結構(遞歸/迭代)
核心思想:分治思想處理子樹,棧/隊列輔助迭代
1. 二叉樹的最大深度(No.104)
# 遞歸
def maxDepth(root):if not root: return 0return 1 + max(maxDepth(root.left), maxDepth(root.right))# 迭代(BFS)
from collections import deque
def maxDepth(root):if not root: return 0queue = deque([root])depth = 0while queue:depth += 1for _ in range(len(queue)):node = queue.popleft()if node.left: queue.append(node.left)if node.right: queue.append(node.right)return depth
2. 驗證二叉搜索樹(No.98)
def isValidBST(root):def valid(node, low=-float('inf'), high=float('inf')):if not node: return Trueif node.val <= low or node.val >= high:return Falsereturn (valid(node.left, low, node.val) and valid(node.right, node.val, high))return valid(root)
3. 二叉樹的最近公共祖先(No.236)
def lowestCommonAncestor(root, p, q):if not root or root == p or root == q:return rootleft = lowestCommonAncestor(root.left, p, q)right = lowestCommonAncestor(root.right, p, q)if left and right: return rootreturn left if left else right
四、排序算法(歸并/快排)
核心思想:分治策略實現高效排序
1. 快速排序模板
def quick_sort(arr, l, r):if l >= r: return# 分區操作pivot = partition(arr, l, r)quick_sort(arr, l, pivot-1)quick_sort(arr, pivot+1, r)def partition(arr, l, r):import random# 隨機選擇基準避免最壞情況rand_idx = random.randint(l, r)arr[rand_idx], arr[r] = arr[r], arr[rand_idx]pivot_val = arr[r]i = lfor j in range(l, r):if arr[j] < pivot_val:arr[i], arr[j] = arr[j], arr[i]i += 1arr[i], arr[r] = arr[r], arr[i]return i
2. 合并區間(No.56)
def merge(intervals):intervals.sort(key=lambda x: x[0])merged = []for interval in intervals:if not merged or merged[-1][1] < interval[0]:merged.append(interval)else:merged[-1][1] = max(merged[-1][1], interval[1])return merged
3. 數組中的第K個最大元素(No.215)
def findKthLargest(nums, k):import heapqmin_heap = []for num in nums:heapq.heappush(min_heap, num)if len(min_heap) > k:heapq.heappop(min_heap)return min_heap[0]
五、動態規劃(狀態轉移)
核心思想:定義狀態與狀態轉移方程,避免重復計算
1. 爬樓梯(No.70)基礎模板
def climbStairs(n):if n <= 2: return ndp = [0]*(n+1)dp[1], dp[2] = 1, 2for i in range(3, n+1):dp[i] = dp[i-1] + dp[i-2]return dp[n]
2. 最長遞增子序列(No.300)
# 標準DP解法 O(n2)
def lengthOfLIS(nums):dp = [1]*len(nums)for i in range(1, len(nums)):for j in range(i):if nums[i] > nums[j]:dp[i] = max(dp[i], dp[j]+1)return max(dp)# 貪心+二分 O(nlogn)
def lengthOfLIS(nums):tails = [] # 存儲最小尾部元素for num in nums:# 二分查找插入位置l, r = 0, len(tails)while l < r:mid = (l+r)//2if tails[mid] < num:l = mid+1else:r = midif l == len(tails):tails.append(num)else:tails[l] = numreturn len(tails)
3. 編輯距離(No.72)經典二維DP
def minDistance(word1, word2):m, n = len(word1), len(word2)dp = [[0]*(n+1) for _ in range(m+1)]# 初始化邊界for i in range(1, m+1): dp[i][0] = ifor j in range(1, n+1): dp[0][j] = jfor i in range(1, m+1):for j in range(1, n+1):if word1[i-1] == word2[j-1]:dp[i][j] = dp[i-1][j-1]else:dp[i][j] = 1 + min(dp[i-1][j], # 刪除dp[i][j-1], # 插入dp[i-1][j-1] # 替換)return dp[m][n]
六、綜合訓練題庫(按難度排序)
類別 | 基礎題(掌握模板) | 進階題(應用變形) | 挑戰題(綜合優化) |
---|---|---|---|
數組 | 26/27/283/167 | 11/15/16/238 | 42/128/239/295 |
哈希表 | 1/202/242 | 49/560/763 | 30/76/146/460 |
樹 | 100/101/104/226 | 102/105/236 | 124/297/337 |
排序 | 75/88/147 | 148/179/215 | 56/164/315 |
DP | 70/118/121 | 62/64/139/198 | 72/152/312/322 |
高效訓練建議:
每日專項訓練:每天專注1個算法類型(如周一數組/周二哈希表)
三遍刷題法:
第一遍:獨立解題(30分鐘)
第二遍:學習最優解并復現
第三遍:隔周重做+總結模板
重點突破:
雙指針(數組/字符串)
回溯法(樹形問題)
狀態機(動態規劃)
堆應用(排序/TOP K問題)
核心技巧:
數組:左右指針/快慢指針/前綴和
哈希表:空間換時間/計數器
樹:遞歸三要素(終止條件/本級任務/返回值)
排序:歸并分治/快速選擇
DP:狀態定義 → 轉移方程 → 初始化 → 遍歷順序