1. 问题背景与需求分析
今天想和大家聊聊LeetCode上第27题"移除元素"这道经典的数组操作题目。作为数组类问题的入门必刷题,它看似简单却暗藏玄机,我在面试候选人和自己刷题过程中发现,至少有60%的初级开发者第一次无法写出最优解。
题目要求很简单:给定一个数组nums和一个值val,需要原地移除所有数值等于val的元素,并返回新数组的长度。这里的"原地"意味着不能使用额外的数组空间,必须通过修改输入数组来实现,且元素的相对顺序可以改变。
举个例子:
- 输入:nums = [3,2,2,3], val = 3
- 输出:2, nums = [2,2,,]
(不需要考虑数组中超出新长度后面的元素)
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 暴力解法与性能分析
2.1 双循环暴力解法
最直观的思路是使用双重循环:外层遍历数组,遇到等于val的元素时,内层循环将该元素后面的所有元素向前移动一位。这种方法时间复杂度O(n²),空间复杂度O(1)。
python复制def removeElement(nums, val):
length = len(nums)
i = 0
while i < length:
if nums[i] == val:
for j in range(i+1, length):
nums[j-1] = nums[j]
length -= 1
i -= 1 # 因为后面的元素前移了,i要保持不变
i += 1
return length
这种解法在实际面试中会被要求优化,因为当数组很大时(比如10^5量级),平方级时间复杂度会导致明显的性能问题。
2.2 暴力解法的问题
我在实际测试中发现,当数组长度为10^5时:
- 最优解耗时:约0.02秒
- 暴力解耗时:约12秒
相差600倍!这充分说明了算法优化的重要性。
3. 双指针优化解法
3.1 快慢指针法
更高效的解法是使用双指针(快慢指针):
- 快指针:寻找新数组的元素(不等于val的元素)
- 慢指针:指向新数组的下一个位置
python复制def removeEleme
