1. 算法实战:双指针技巧的三种经典应用
双指针算法是解决数组和链表问题的利器,今天我们就通过力扣的三道经典题目(27.移除元素、977.有序数组的平方、209.长度最小子数组),深入剖析快慢指针、双向指针和滑动窗口这三种双指针变体的应用场景和实现细节。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 移除元素问题解析
2.1 问题描述与暴力解法
给定一个数组nums和一个值val,需要原地移除所有数值等于val的元素,并返回新数组的长度。要求不使用额外数组空间,元素的顺序可以改变。
暴力解法的思路是发现目标值后,将后续所有元素前移一位,时间复杂度O(n²):
java复制// 暴力解法(仅示意,不推荐)
for (int i = 0; i < size; i++) {
if (nums[i] == val) {
for (int j = i + 1; j < size; j++) {
nums[j - 1] = nums[j];
}
i--; // 因为下标i以后的数值都向前移动了一位
size--;
}
}
注意:这种解法在LeetCode上会超时,仅用于理解问题本质
2.2 快慢指针法实现
快慢指针法将时间复杂度优化到O(n),空间复杂度O(1):
- 快指针:寻找新数组需要的元素(即不等于val的元素)
- 慢指针:指向新数组的写入位置
java复制class Solution {
public int removeElement(int[] nums, int val) {
int slow = 0;
for (int fast = 0; fast < nums.length; fast++) {
if (nums[fast] != val) {
nums[slow] = nums[fast];
slow++;
}
}
return slow;
}
}
关键点解析:
- 赋值操作nums[slow] = nums[fa
