双指针算法

双指针核心思想

按照目前的理解,抽象出的一句话是

两个数据的变化具有一定的关联关系时可以考虑双指针

例如,在一有序数组中,找到和为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;
}

相关练习题

原文地址:https://www.cnblogs.com/G-H-Y/p/14289923.html