算法学习系列文章----玩转双指针

目录

 

1.算法解释

 1.1指针与常量

   1.2指针函数与函数指针

   1.3 Two Sum


1.算法解释

    双指针主要用于遍历数组,两个指针指向不同的元素,从而协同完成任务。也可以延伸到多个数组的多个指针。

    若两个指针指向同一数组,遍历方向相同且不会相交,则也称为滑动窗口(两个指针包围的区域即为当前窗口),经常用于区间搜索。

    若两个指针指向同一数组,但是遍历方向相反,则可以用来进行搜索,待搜索的数组往往是排好序的。

    对于C++语言,指针还可以玩出很多新的花样。一些常见的关于指针的操作如下。

 1.1指针与常量

    int x;

    int * p1=&x;   //指针可以被修改,值也可以被修改;

    const int * p2=&x;    //指针可以被修改,值也可以被修改(const int)

    int * const p3=&x;   //指针不可以被修改(* const),值可以被修改

    const int * const p4 = &x;   //指针不可以被修改,值也不可以被修改

   1.2指针函数与函数指针

      //addition是指针函数,一个返回类型是指针的函数

      int* addition(int a,int b) {

       int* sum=new int(a+b);

       return sum;

      }

      int subtraction(int a,int b) {

       return a-b;

      }

      int operation(int x,int y,int (*func)(int ,int)) {

      return (*func)(x,y);

      }

     //minux是函数指针,指向函数的指针

    int (*minuxs)(int,int) = subtraction;

    int* m = addition(1,2);

    int n = operation(3,*m,minus);

   1.3 Two Sum

  Two Sum || - Input array is sorted(Easy)

  题目描述:在一个增序的整数里找到两个数,使它们的和为给定值。已知有且只有一对解;

  输入输出样例,输入是一个数组(numbers)和一个给定值(target)。输出是两个数的位置,从1开始计数。

  Input:numbers = [2,7,11,15]   ,  target = 9;

  Output : [1,2]

  题解:因为数组已经排好序,我们可以采用方向相反的双指针来寻找这两个数字,一个初始指向最小的元素,即数组最右边,向右遍历;一个初始指向最大的元素,即数组最右边,向左遍历。

  如果两个指针指向元素的和等于给定值,那么他们就是我们想要的结果,如果两个指针指向元素的和小于给定值,我们把左边的指针右移一位,使得当前的和增加一点。如果两个指针指向元素的和大于给定值,我们把右边的指针左移一位,使得当前的和减少一点。

   可以证明,对于排序且有解的数组,双指针一定能遍历到最优解。证明方法如下:假设最优解的两个数的位置分别是L和R。我们假设在左指针在L左边的时候,右指针已经移动到了R;此时两个指针指向值的和小于给定值,因此左指针会一直右移动知道到达L。同理,如果我们假设在右指针在R的时候,左指针已经移动到了L;此时两个指针指向值的和大于给定值,因此右指针会一直左移动知道到达R。所以双指针在任何时候都不可能处于(L,R)之间,又因为不满足条件时指针必须移动一个,所以最终一定会收敛在L和R;

vector<int> twoSum(vector<int>& numbers, int target) {
    int l = 0, r = numbers.size() - 1, sum;
    while (l < r) {
        sum = numbers[l] + numbers[r];
        if (sum == target) break;
        if (sum < target) ++l;
        else --r;
    }
    return vector<int>{l + 1, r + 1};
}

猜你喜欢

转载自blog.csdn.net/qq_25580555/article/details/115444127