1. 力扣Hot100普通数组题型解析
力扣(LeetCode)的Hot100题库是算法面试准备的黄金标准,其中普通数组类题目占据了重要位置。这类题目看似基础,却蕴含着丰富的解题技巧和算法思想。作为刷过300+数组题的老手,我发现数组问题主要考察以下几个核心能力:
- 对数组基本操作(遍历、查找、排序)的熟练度
- 边界条件的处理能力
- 时间/空间复杂度的优化意识
2. 高频考点与解题模板
2.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
- 相向指针(适用于有序数组)
python复制def twoSum(nums, target):
left, right = 0, len(nums)-1
while left < right:
s = nums[left] + nums[right]
if s == target:
return [left+1, right+1]
elif s < target:
left += 1
else:
right -= 1
- 滑动窗口(子数组问题首选)
python复制def minSubArrayLen(target, nums):
left = total = 0
res = float('inf')
for right in range(len(nums)):
total += nums[right]
while total >= target:
res = min(res, right-left+1)
total -= nums[left]
left += 1
return res if res != float('inf') else 0
2.2 前缀和与哈希表
当遇到子数组和问题时,前缀和+哈希表是O(n)时间复杂度的最优解:
python复制def subarraySum(nums, k):
from collections import defaultdict
prefix = defaultdict(int)
prefix[0] = 1
res = curr = 0
for num in nums:
curr += num
res += prefix.get(curr - k, 0)
prefix[curr] += 1
return res
关键点:初始化prefix[0]=1是为了处理从数组起始位置开始的子数组
3. 典型题目深度剖析
3.1 最大子数组和(53题)
这道题可以用Kadane算法在O(n)时间内解决:
python复制def maxSubArray(nums):
curr_max = global_max = nums[0]
for num in nums[1:]:
curr_max = max(num, curr_max + num)
global_max = max(global_max, curr_max)
return global_max
变式思考:如果要返回最大子数组本身而不仅是和,该如何修改代码?
3.2 合并区间(56题)
处理区间问题的标准流程:
- 按起始位置排序
- 逐个合并重叠区间
python复制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
4. 常见陷阱与优化技巧
4.1 边界条件处理
数组题最容易出错的三种边界情况:
- 空数组输入(如[])
- 单元素数组(如[1])
- 全相同元素数组(如[2,2,2])
防御性编程建议:
python复制if not nums: # 处理空数组
return 0
if len(nums) == 1: # 处理单元素
return nums[0]
4.2 空间复杂度优化
很多数组题可以通过原地修改来优化空间:
python复制# 错误示范:创建了新数组
result = []
for num in nums:
result.append(num*2)
# 正确做法:原地修改
for i in range(len(nums)):
nums[i] *= 2
5. 进阶挑战与扩展思考
5.1 二维数组处理
旋转图像(48题)展示了二维数组的经典操作:
python复制def rotate(matrix):
n = len(matrix)
# 先转置
for i in range(n):
for j in range(i, n):
matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
# 再水平翻转
for row in matrix:
row.reverse()
5.2 数学性质应用
寻找缺失的第一个正数(41题)需要利用数组索引作为哈希表:
python复制def firstMissingPositive(nums):
n = len(nums)
# 第一次遍历:将数字放到正确位置
for i in range(n):
while 1 <= nums[i] <= n and nums[nums[i]-1] != nums[i]:
nums[nums[i]-1], nums[i] = nums[i], nums[nums[i]-1]
# 第二次遍历:找出第一个不符合的位置
for i in range(n):
if nums[i] != i+1:
return i+1
return n+1
6. 刷题路线建议
根据我的面试经验,建议按以下顺序攻克数组题:
- 基础遍历:27、26、80
- 双指针:167、15、16
- 滑动窗口:209、3、76
- 前缀和:560、238、724
- 区间问题:56、57、252
- 二维数组:48、54、73
每道题至少做两遍:第一遍理解思路,第二遍独立实现。遇到特别难的题目可以记录解题日记,写下自己的思考过程。
