1. LeetCode 1-10题解析:从零开始的算法思维训练
刷LeetCode已经成为程序员提升算法能力的必经之路。作为算法题库的标杆,LeetCode前10题虽然看似基础,却蕴含着编程思维的核心要素。我花了三个月时间系统刷完前100题,发现1-10题正是构建算法思维的基石。这些题目涵盖了数组操作、哈希表应用、字符串处理等基础场景,每道题都有至少三种解法,适合不同阶段的开发者反复揣摩。
新手常见误区是直接看答案,但真正有效的学习方式是先自己思考,哪怕花上几个小时。我在第1题"两数之和"上卡了整整一天,这种挫败感恰恰是算法能力提升的关键催化剂。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 题目详解与多解法实现
2.1 第1题:两数之和(Two Sum)
这是大多数人的算法启蒙题。给定数组nums和目标值target,返回和为target的两个元素下标。暴力解法是双重循环遍历,时间复杂度O(n²):
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复制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
实战技巧:当输入数组已排序时,可以使用双指针法,空间复杂度可优化到O(1)。我在面试中曾被要求实现这个变种。
2.2 第2题:两数相加(Add Two Numbers)
链表操作的经典题目。给定两个非空链表表示的非负整数,每位数字逆序存储,返回两数之和的链表形式。关键点在于处理进位和不同长度链表:
python复制def addTwoNumbers(l1, l2):
dummy = ListNode(0)
current = dummy
carry = 0
while l1 or l2 or carry:
sum_val = carry
if l1:
sum_val += l1.val
l1 = l1.next
if l2:
sum_val += l2.val
l2 = l2.next
carry, val = divmod(sum_val, 10)
current.next = ListNode(val)
current = current.next
return dummy.next
避坑指南:容易遗漏最后的进位(如5+5=10),我曾在周赛中因此失分。建议用dummy节点简化边界处理。
2.3 第3题:无重复字符的最长子串(Longest Substring Without Repeating Characters)
滑动窗口算法的典型应用。维护一个字符到索引的哈希表,当遇到重复字符时更新窗口左边界:
python复制def lengthOfLongestSubstring(s):
char_index = {}
left = max_len = 0
for right, char in enumerate(s):
if char in char_index and char_index[char] >= left:
left = char_index[char] + 1
char_index[char] = right
max_len = max(max_len, right - left + 1)
return max_len
性能优化:使用数组代替哈希表可以进一步提升速度,特别是当字符集较小时(如仅字母)。
3. 解题方法论与进阶技巧
3.1 第4题:寻找两个正序数组的中位数(Median of Two Sorted Arrays)
这道hard题考验对二分查找的深刻理解。最优解法的时间复杂度是O(log(min(m,n)))。关键思路是将两个数组分割成左右两部分,使得左边元素数量等于右边,且左边最大值小于右边最小值:
python复制def findMedianSortedArrays(nums1, nums2):
A, B = nums1, nums2
if len(A) > len(B):
A, B = B, A
m, n = len(A), len(B)
left, right = 0, m
while left <= right:
i = (left + right) // 2
j = (m + n + 1) // 2 - i
if i < m and B[j-1] > A[i]:
left = i + 1
elif i > 0 and A[i-1] > B[j]:
right = i - 1
else:
max_left = max(A[i-1] if i > 0 else float('-inf'),
B[j-1] if j > 0 else float('-inf'))
if (m + n) % 2 == 1:
return max_left
min_right = min(A[i] if i < m else float('inf'),
B[j] if j < n else float('inf'))
return (max_left + min_right) / 2
调试心得:边界条件极其复杂,建议画出分割线示意图。我用了六个测试用例才覆盖所有边界情况。
3.2 第5题:最长回文子串(Longest Palindromic Substring)
动态规划和中心扩展两种主流解法。中心扩展法更优,时间复杂度O(n²):
python复制def longestPalindrome(s):
def expand(l, r):
while l >= 0 and r < len(s) and s[l] == s[r]:
l -= 1
r += 1
return s[l+1:r]
res = ""
for i in range(len(s)):
odd = expand(i, i)
even = expand(i, i+1)
res = max(res, odd, even, key=len)
return res
优化技巧:Manacher算法可以将时间复杂度降到O(n),适合准备算法竞赛时掌握。
4. 常见问题与周赛策略
4.1 第6-10题核心考点
- Z字形变换:字符串的行索引计算,找出数学规律
- 整数反转:溢出处理是重点,Python需要特殊处理
- 字符串转换整数:有限状态机(DFA)的经典应用
- 回文数:不转换为字符串的数学解法
- 正则表达式匹配:动态规划最难题目之一
4.2 LeetCode周赛备战指南
根据我参加30+场周赛的经验,前两题通常相当于题库的easy-medium难度。针对第430场周赛:
- 前10分钟快速解决前两题
- 第三题往往需要特定算法(如贪心、DFS)
- 最后一题通常是hard,建议先确保前三题正确
时间分配建议:
- 第一题:5分钟
- 第二题:10分钟
- 第三题:20分钟
- 第四题:剩余时间+罚时
4.3 伸展树(Splay Tree)在LeetCode的应用
虽然LeetCode不直接考察伸展树,但其"访问热点"特性与LRU缓存机制相似。理解伸展树有助于解决类似问题:
- 最近访问的元素会移动到根部
- 均摊时间复杂度O(log n)
- 不需要存储额外平衡信息
在解决设计类问题时(如第146题LRU缓存),可以借鉴伸展树的思路。
5. 高效刷题路线图
5.1 新手百日计划
根据热门100题分类,建议学习路径:
| 阶段 | 时间 | 重点题型 | 每日题量 |
|---|---|---|---|
| 1 | 1-30天 | 数组、字符串、哈希表 | 2-3 |
| 2 | 31-60天 | 链表、双指针、滑动窗口 | 3-4 |
| 3 | 61-90天 | 二叉树、DFS/BFS | 4-5 |
| 4 | 91-100天 | 动态规划、贪心 | 5+ |
5.2 代码模板与速查表
二分查找通用模板:
python复制def binary_search(arr, target):
left, right = 0, len(arr)-1
while left <= right:
mid = left + (right-left)//2
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
DFS回溯模板:
python复制def backtrack(path, choices):
if meet_condition:
results.append(path)
return
for choice in choices:
if valid(choice):
make_choice(choice)
backtrack(path, new_choices)
undo_choice(choice)
5.3 调试与性能分析技巧
- 对拍测试:用暴力解法作为对照,验证优化解的正确性
- 边界测试:空输入、极值、重复元素等特殊情况
- Python性能工具:
python复制import cProfile cProfile.run('your_function()') - 可视化调试:对于树/图问题,先画出测试用例的图示
我在解决第10题"正则表达式匹配"时,通过绘制状态转移图,终于理解了动态规划表的填充过程。这种可视化方法后来成为我解决复杂DP问题的标准流程。
