前言
一刷代码随想录,今天的内容是 快慢指针。
欢迎大家在评论区留言发表自己的看法,如文章有不妥之处,请批评指正。
一、快慢指针模板
双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。
- 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
- 慢指针:指向更新 新数组下标的位置
// 数组中快慢指针模板
int n = nums.size();
int fast = 0, slow = 0;
for (fast = 0; fast < n; ++fast) {
if (nums[fast] != val) {
// 题目给的判断条件
nums[slow++] = nums[fast]; // 不满足条件的情况进行替换,满足条件后又遇到不满足的情况依然如此替换
}
}
return slow;
快慢指针中,在没有满足条件前,使用 类似nums[slow++] = nums[fast];
,而不能凭借想象说想把两个指针指向满足条件的数的情况下再来进行操作而使用 ++slow;++fast;
,前者能保证在满足条件之后的数据不满足条件的情况下,仍然能将 fast
指向的元素替换到 slow
指向的元素,而后者却不能。
二、练习题目
三、源码剖析
1、27. 移除元素|★★★☆☆(第一题,看了题解)
第一版:快慢指针(题解)
时间复杂度:O(n)
,空间复杂度:O(1)
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
// 双指针,快慢指针
// 快慢指针的要点是,弄清楚快指针和慢指针的职责
int n = nums.size();
int fast = 0, slow = 0;
for (fast = 0; fast < n; ++fast) {
if (nums[fast] != val) {
nums[slow++] = nums[fast];
}
}
return slow;
}
};
第二版:相向双指针(题解)
时间复杂度:O(n)
,空间复杂度:O(1)
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
// 相向双指针
// 基于题目说元素的顺序可以改变,因此可以前后一个指针,前面的指针找到等于val的地方,后面的指针找到不等于val的地方,然后用后面的覆盖前面的
int l = 0, r = nums.size() - 1;
while (l <= r) {
// 前面找到等于val的地方
while (l <= r && nums[l] != val) {
++l;
}
// 后面找到不等于val的地方
while (l <= r && nums[r] == val) {
--r;
}
if (l < r) {
nums[l++] = num