1. LeetCode 1-25题算法解析入门指南
第一次刷LeetCode时,面对前25道简单题我完全摸不着头脑——明明每道题都能看懂题目,但就是不知道如何下手。经过三个月系统训练后,我才发现这些"简单题"其实是算法学习的黄金钥匙。它们像乐高积木一样,通过不同组合能构建出解决复杂问题的思维框架。
前25题主要覆盖六大核心算法类型:数组操作(如两数之和)、字符串处理(如反转字符串)、数学计算(如回文数)、链表基础(如合并两个有序链表)、二分查找(如搜索插入位置)和位运算(如汉明距离)。掌握这些基础题型后,后续中等难度题目中70%都能找到它们的变形或组合。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心算法类型与解题框架
2.1 数组类问题实战解析
以经典的#1两数之和为例,新手最容易陷入暴力枚举的双重循环陷阱。我在初期提交的代码是这样的:
python复制def twoSum(nums, target):
for i in range(len(nums)):
for j in range(i+1, len(nums)):
if nums[i] + nums[j] == target:
return [i, j]
这种O(n²)时间复杂度解法在数组较大时性能急剧下降。通过引入哈希表(Python中的字典),可以将时间复杂度优化到O(n):
python复制def twoSum(nums, target):
hashmap = {}
for i, num in enumerate(nums):
complement = target - num
if complement in hashmap:
return [hashmap[complement], i]
hashmap[num] = i
关键技巧:数组问题优先考虑能否用空间换时间,哈希表是降低时间复杂度的利器
2.2 字符串处理的三板斧
#14最长公共前缀展示了字符串处理的典型思路。我最初的做法是逐字符比较所有字符串:
python复制def longestCommonPrefix(strs):
if not strs:
return ""
min_len = min(len(s) for s in strs)
for i in range(min_len):
char = strs[0][i]
if any(s[i] != char for s in strs):
return strs[0][:i]
return strs[0][:min_len]
更优雅的解法是利用Python的zip和set特性:
python复制def longestCommonPrefix(strs):
prefix = []
for chars in zip(*strs):
if len(set(chars)) == 1:
prefix.append(chars[0])
else:
break
return "".join(prefix)
避坑指南:字符串边界情况要特别注意空列表、空字符串和单元素情况
3. 算法优化进阶技巧
3.1 双指针法的精妙运用
#26删除有序数组中的重复项是双指针法的经典案例。我的第一版代码使用了额外的存储空间:
python复制def removeDuplicates(nums):
unique = []
for num in nums:
if num not in unique:
unique.append(num)
nums[:] = unique
return len(unique)
实际上只需要O(1)空间的双指针解法:
python复制def removeDuplicates(nums):
if not nums:
return 0
slow = 0
for fast in range(1, len(nums)):
if nums[fast] != nums[slow]:
slow += 1
nums[slow] = nums[fast]
return slow + 1
3.2 位运算的魔法
#136只出现一次的数字展示了位运算的高效性。常规解法会用哈希表统计次数:
python复制def singleNumber(nums):
from collections import defaultdict
counts = defaultdict(int)
for num in nums:
counts[num] += 1
for num, count in counts.items():
if count == 1:
return num
而使用异或运算可以将空间复杂度降到O(1):
python复制def singleNumber(nums):
result = 0
for num in nums:
result ^= num
return result
原理揭秘:a ^ a = 0,a ^ 0 = a,异或满足交换律和结合律
4. 高频问题分类精讲
4.1 链表基础操作
#21合并两个有序链表是理解递归的绝佳例题。迭代解法:
python复制def mergeTwoLists(l1, l2):
dummy = ListNode()
current = dummy
while l1 and l2:
if l1.val < l2.val:
current.next = l1
l1 = l1.next
else:
current.next = l2
l2 = l2.next
current = current.next
current.next = l1 if l1 else l2
return dummy.next
递归解法更简洁:
python复制def mergeTwoLists(l1, l2):
if not l1 or not l2:
return l1 or l2
if l1.val < l2.val:
l1.next = mergeTwoLists(l1.next, l2)
return l1
else:
l2.next = mergeTwoLists(l1, l2.next)
return l2
4.2 二分查找变体
#35搜索插入位置展示了标准二分查找的变形。关键点在于理解循环不变式和终止条件:
python复制def searchInsert(nums, target):
left, right = 0, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return left
调试技巧:对于二分查找,在纸上画出左右指针移动过程最直观
5. 实战问题排查与优化
5.1 边界条件处理
#20有效的括号教会我重视边界条件。初期忽略空字符串判断:
python复制def isValid(s):
stack = []
mapping = {')': '(', '}': '{', ']': '['}
for char in s:
if char in mapping:
top = stack.pop() if stack else '#'
if mapping[char] != top:
return False
else:
stack.append(char)
return not stack
5.2 算法选择误区
#9回文数展示了算法选择的艺术。将数字转为字符串虽然简单:
python复制def isPalindrome(x):
return str(x) == str(x)[::-1]
但数学解法更有训练价值:
python复制def isPalindrome(x):
if x < 0 or (x % 10 == 0 and x != 0):
return False
reverted = 0
while x > reverted:
reverted = reverted * 10 + x % 10
x //= 10
return x == reverted or x == reverted // 10
6. 刷题方法论与资源推荐
建立个人解题模板库是关键。我将前25题归纳为以下模式:
- 哈希映射:两数之和、字母异位词
- 双指针:移除元素、删除重复项
- 栈应用:有效括号、最小栈
- 位运算:只出现一次数字、汉明距离
- 二分变形:搜索插入位置、平方根
推荐按题型而非题号顺序刷题。例如先集中攻克所有数组题,再转向字符串类。每道题尝试至少两种解法,比较时间/空间复杂度差异。
