本篇博客是参照cyc的博客写的,双指针部分
167.两数之和||-输入有序数组
因为输入的数组是升序排列的有序数组,要找到两个数使得他们相加之和等于目标数。
所以利用升序排列的特性,双指针,一个放头,一个放尾。如果两数相加之和小于目标数,头指针++,如果两数相加之和小于目标数,尾指针--;
class Solution { public: vector<int> twoSum(vector<int>& numbers, int target) { int i=0,j=numbers.size()-1; while(j>i){ if(numbers[i]+numbers[j]==target){ return {i+1,j+1}; } if(numbers[i]+numbers[j]<target)++i; if(numbers[i]+numbers[j]>target)--j; } return {-1,-1}; } };
633.平方数之和
也是一个头指针一个尾指针,要判断是否存在两个数a和b使得a^2+b^2=c.那么头指针从0开始,尾指针从sqrt(c)开始,两数平方相加,如果大于c就将头指针++,如果小于c就将尾指针--,直到等于c或者头指针大于尾指针。
class Solution { public: bool judgeSquareSum(int c) { long long min=0; long long max=sqrt(c); long long sum; while(min<=max){ sum=min*min+max*max; if(sum==c) return true; if(sum<c)min++; if(sum>c)max--; } return false; } };
345.反转字符串中的元音字母
反转字符串中的元音字母,同样使用双指针,一个在字符串头,一个在字符串尾。哪个指到元音就停下,直到两个指针都指到元音,进行交换再继续往后走。
class Solution { public: string reverseVowels(string s) { string a="aeiouAEIOU"; int i=0; int j=s.size()-1; while(i<j) { while(!(a.find(s[i])<a.length())&&i<j) i++; while(!(a.find(s[j])<a.length())&&i<j) j--; swap(s[i++],s[j--]); } return s; } };
680.验证回文字符串||
回文字符串就是指对称的字符串,所以双指针一个放在头,一个放在尾,判断头和尾是不是相等。因为可以删除一个字符。所以对于不同的字符要分别对左和右进行删除处理,使用递归刚刚好。
class Solution { public: bool validPalindrome(string s) { return sfhw(s, 0, s.size()-1, 0); } bool sfhw(string s, int index1, int index2, int flag){ //flag代表是否跳过 while(index1 < index2){ if(s[index1] == s[index2]){index1 ++; index2 --;} else{ if(flag == 1) return false; //如果已经跳过, 直接返回否 else return sfhw(s, index1+1, index2, 1) || sfhw(s, index1, index2-1, 1); } } return true; } };
88.合并两个有序数组
就将数组2的内容加到数组1中,将数组1排序。
class Solution { public: void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) { for(int j=0;j<n;j++){ nums1[j+m]=nums2[j]; } sort(nums1.begin(),nums1.end()); } };