0 简介
双指针算法在一些数组题中很常用,它指的是一类使用两个指针遍历数组求解问题的方法,这里的指针是广义上的,有可能是c/c++中的指针,也有可能仅仅是两个整数下标。双指针算法有两种形式,一种被称为对撞指针,两个指针从两端向中间靠拢;另一种是快慢指针,两个指针向统一方向运动,滑动窗口方法就是一种常用的快慢指针方法。
1 对撞指针
对撞指针的思想如前所述,下面举一道具体的例题来说明。这道题是leetcode345题。题目描述如下
编写一个函数,以字符串作为输入,反转该字符串中的元音字母。
示例 1:
输入: “leetcode”
输出: “leotcede”
使用对撞指针的思路便是初始化两个指针i,j位于字符串起始末尾,i向右寻找原音字母,找到停下;j向左寻找元音字母,找到停下;接着二者交互直到i>j;具体代码中注意一下数组越界的问题就好;
代码如下:
class Solution {
public:
string reverseVowels(string s)
{
for(int i = 0,j = s.size()-1; i < j;)
{
while(i < s.size() && !isVowet(s[i]))
++i;
while(j > 0 && !isVowet(s[j]))
--j;
if(i < j)
std::swap(s[i],s[j]);
++i,--j;
}
return s;
}
bool isVowet(char c)//判断元音字母
{
if(c == 'a' || c == 'o' || c == 'e'
|| c == 'i' || c == 'u')
return true;
if(c == 'A' || c == 'O' || c == 'E'
|| c == 'I' || c == 'U')
return true;
else
return false;
}
};
2 滑动窗口
滑动窗口在字符串题目中很常见,我们设置两个指针向同一方向运动,根据具体的条件滑动指针。下面结合一道具体的题目来说明,leetcode第3题。题目描述:
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3
这道题可以使用双指针算法。首先我们定义两个指针i=0,j=-1,然后预备一个buf[256],用于统计字符出现的次数。如果一个字符没有出现过,则滑动j指针,否则滑动i指针。每次滑动之后,判定一下当前字符长度是否是最大长度即可。代码如下
class Solution {
public:
int lengthOfLongestSubstring(string s)
{
int i = 0,j = -1;
int maxLen = 0;
char buf[256];
memset(buf,0,sizeof(buf));
while(i < s.size())
{
if(j+1 < s.size() && buf[s[j+1]] == 0)
{
++j;
buf[s[j]] = 1;
}
else
{
buf[s[i]] = 0;
++i;
}
maxLen = max(maxLen,j-i+1);
}
return maxLen;
}
};