167
思想:找到的两个数一定是一左一右的。
Nums[i]+nums[j]<target:i++
Nums[i]+nums[j]>target:j--
直到nums[i]+nums[j]=target
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
//对撞指针思想 因为是有序数组,在数组两侧分别找一个结果
int l=0, r=numbers.size()-1;
while(l<r){
if(numbers[l] + numbers[r] == target)
{
int res[2]={l+1,r+1};
return vector<int>(res,res+2);
}else if(numbers[l] + numbers[r] > target)
r--;
else
l++;
}
return vector<int>();
}
};
125
/**
给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
输入: "A man, a plan, a canal: Panama"
输出: true
输入: "race a car"
输出: false
*/
class Solution {
public:
bool isPalindrome(string s) {
//空字符串
if(s.size()==0) return true;
//使用双指针对撞思想,一个指针从头开始遍历,一个指针从尾开始,看有效字符是否相同
int r=0, l=s.size()-1;
while(r<l)
{
if(isalnum(s[r])==0) r++; //找到符合要求的字符
else if(isalnum(s[l])==0) l--; //找到符合要求的字符
else
{
if(toupper(s[r]) == toupper(s[l]))
{
l--;
r++;
}else
return false;
}
}
return true;
}
};
344
/**
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
输入:["h","e","l","l","o"]
输出:["o","l","l","e","h"]
*/
class Solution {
public:
void reverseString(vector<char>& s) {
//对撞指针,对换位置
int l=0,r=s.size()-1;
while(l<r)
{
swap(s[r],s[l]);
l++;
r--;
}
}
};
345
/**
编写一个函数,以字符串作为输入,反转该字符串中的元音字母。
输入: "hello"
输出: "holle"
*/
class Solution {
public:
string reverseVowels(string s) {
//双指针思想 找到左右两个元音,交换位置
int l=0,r=s.size()-1;
while(l<r)
{
if(is_ok(s[l])==0) l++;
else if(is_ok(s[r])==0) r--;
else
{
swap(s[l],s[r]);
l++;
r--;
}
}
return s;
}
bool is_ok(char ch){
if(ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u'||
ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U')
return true;
return false;
}
};
11
思想:
/**
给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点(i,ai) 。
在坐标内画 n 条垂直线,垂直线 i的两个端点分别为(i,ai) 和 (i, 0)。
找出其中的两条线,使得它们与x轴共同构成的容器可以容纳最多的水。
输入:[1,8,6,2,5,4,8,3,7]
输出:49
*/
class Solution {
public:
int maxArea(vector<int>& height) {
//双指针思想 向内移动短板 短板可能变大 S可能变大
int l=0,r=height.size()-1;
int ret = min(height[r],height[l])*(r-l); //计算初始面积
while(l<r)
{
if(height[l]>height[r]) //右边板短
{
r--;
}else{ //左边板短
l++;
}
int area = min(height[l],height[r])*(r-l);
if(area > ret)
ret =area;
}
return ret;
}
int min(int x,int y)
{
if(x<y)
return x;
else
return y;
}
};
15
#include <iostream>
#include <map>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
/**
给你一个包含 n 个整数的数组nums,判断nums中是否存在三个元素 a,b,c ,
使得a + b + c = 0请你找出所有满足条件且不重复的三元组。
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
*/
class Solution {
public:
vector< vector<int> > threeSum(vector<int>& nums) {
//排序,固定一个数,用对撞指针
vector< vector<int> > res;
sort(nums.begin(),nums.end());//排序
int l=0;
int r=nums.size()-1;
for(int i=0; i<nums.size(); i++)
{
int target= 0-nums[i];//减掉第一个数字后的目标
//在数组的后端寻找答案
l=i+1;
r=nums.size()-1;
while(l<r)
{
if(nums[l]+nums[r]>target)
r--;
else if(nums[l]+nums[r]<target)
l++;
else //找到符合条件的
{
int restmp[3]={nums[i],nums[l],nums[r]};
vector<int> vec(restmp,restmp+3);
res.push_back(vec);
//去重[-2,0,0,2,2]
while(l+1<r && nums[l]==nums[l+1]) // 左边的下一个数字如果和现在的重复,则跳过
l++;
while(l<r-1 && nums[r]==nums[r-1]) // 右边的下一个数字如果和现在的重复,则跳过
r--;
l++;
r--;
}
}
//去重 当以一个数开头用过后,后面以这个数字开头的就是重复的 全部跳过
while(i+1<nums.size()&&nums[i]==nums[i+1])
i++;
}
return res;
}
};