一、双指针
指的是在遍历数组的时候采用两个指针访问的方法。如果两个指针方向相反,则称 对撞指针 ;如果两个指针方向相同,则称 快慢指针 ;如果两个指针分属于不同的数组,则称 分离双指针 。 在数组问题中,暴力算法的时间复杂度往往是O(n*n),但双指针利用数组区间单调性的性质,可将时间复杂度降至O(n)。
1.对撞指针
指的是left、right两个指针分别指向数组第零个和最后一个元素,然后左指针不断向右递增,右指针不断向左递减,直到两个指针的值对撞(即left==right)或满足其他要求的特殊条件时结束循环。 适用范围: 解决有序数组或字符串问题:查找有序数组中满足某条件的元素问题(二分查找、数字之和等) 字符串反转问题(反转字符串、回文数、颠倒二进制等问题)
举例说明: 两数之和---给定一个升序排列的数组和一个target值,找到满足相加和为target的两个数,返回它们的下标。 如果是暴力算法,双层for循环,现可改进至单层循环。 (if 两数之和==target,返回下标;if >,right左移;if <,left右移) 验证回文串---给定字符串s,判断是否为回文序列。 (if s[left]==s[right],left右移 right左移;if不等,返回不是回文串;if left==right,返回是回文串)
2.快慢指针
指的是两个指针从数组同一侧开始遍历元素,但两指针以不同的速度、不同的判断条件移动,直到快指针移动到数组尾端,或两指针相交或满足其他特殊条件时结束。 适用范围: 处理数组中的移动、删除元素问题(链表中的判断是否有环、长度问题,还没学)
举例说明: 删除有序数组中的重复项 (slow指向0元素,fast指向1元素;if arr[fsat]!=arr[slow],则slow右移,将fast的元素复制给slow的位置;fast右移;直到fast指向最后元素) (即满足某条件slow才可右移,但满足另一条件或不用满足条件,fast右移)
3.分离双指针
指的是两个指针分属于不同的数组,两个指针分别在两个数组中移动。 适用范围: 处理有序数组合并,求交集、求并集问题。
举例说明: 求两个有序数组的交集 (无序要先排序。两指针left_1,left_2分别指向两数组第0个元素,if arr1[left_1]==arr2[left_2],将该元素添加到新数组中,两指针都右移一;if <,left_1右移;if >,left_2右移;注意答案去重)
二、双指针题目练习
1(344).反转字符串
class Solution {
public:
void reverseString(vector<char>& s) {
int left,right;
char tmp;
int n=s.size();
left=0;
right=n-1;
do
{
tmp=s[left];
s[left]=s[right];
s[right]=tmp;
left+=1;
right-=1;
}while(left!=right);
}
};
//朋友们,这个while里头用==就正常运行,用!=就执行错误,这是咋回事啊!!
2(345).反转字符串中的元音字母
class Solution {
public:
string reverseVowels(string s) {
int left,right;
int n=s.size();
char tmp;
int flag=0;
for(left=0,right=n-1;left==right;left++,right--)
{
if(s[left]!='a'&&s[left]!='e'&&s[left]!='o'
&&s[left]!='u'&&s[left]!='i')
left++;
if(s[right]!='a'&&s[right]!='e'&&s[right]!='i'
&&s[right]!='o'&&s[right]!='u')
right--;
//cout<<left<<","<<right;
tmp=s[left];
s[left]=s[right];
s[right]=tmp;
if(left==right)
break;
}
return s;
}
};
我真服了,咋也不对
3(15).三数之和
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
int left,mid,right;
int n=nums.size();
int ans[1000][3];
right=n-1;
for(left=0;mid==right;left++)
{
mid=left+1;
if(nums[left]+nums[mid]+nums[right]==0)
{
mid++;
continue;}
mid++;
}
}
return ans[][];
};