目录
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};
}