双指针核心思想
按照目前的理解,抽象出的一句话是
两个数据的变化具有一定的关联关系时可以考虑双指针
例如,在一有序数组中,找到和为0
的两个数的所有数对
设一组解为 a + b == 0
,那么当a
增大为a'
时,设对应的可行解为a' + b' == 0
,显然,b' < b
即随着a
的增大,b
的可行解一定在之前解的左侧。该性质的存在使得不再需要让b
逐一枚举所有值
a
从小到大,b
从大到小,使用两个指针维护它们的位置,两者均从两侧向中间运动,复杂度即从(O(N^2))降低为(O(N))
例子1-unique去重函数
// <algorithm>中现成的函数unique应用示例
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector<int> a;
int i = 0;
while (i ++ < 5)
{
a.push_back(i);
a.push_back(i);
}
for (int i = 0; i < a.size(); ++ i) cout << a[i] << ' '; cout << endl;
unique(a.begin(), a.end());
for (int i = 0; i < a.size(); ++ i) cout << a[i] << ' ';
return 0;
}
输出结果:
可以看出它的实现逻辑就是把不重复的数据放到前面,后面的元素不动
// 使用双指针算法实现unique
// 偏向真正的实现方式
vector<int>::iterator unique(vector<int>::iterator begin, vector<int>::iterator end)
{
vector<int>::iterator j = begin;
for (vector<int>::iterator i = begin; i != end; ++ i)
if (i == begin || *i != *(i - 1))
*(j ++ ) = *i;
return j;
}
// 简易版本,更好体现双指针算法
vector<int>::iterator unique(vector<int> &vec)
{
int j = 0;
for (int i = 0; i < vec.size(); ++ i)
if (!i || vec[i] != vec[i - 1])
vec[j ++] = vec[i];
return vec.begin() + j;
}