//167 在有序数组中寻找值为target的两个值的位置(索引+1)
vector<int> twoSum(vector<int>& numbers, int target) {
int i = 0,j=numbers.size()-1;//刚开始我把j=numbers.size(),导致错误
vector<int> result;
while(i<j){
if(numbers[i]+numbers[j]==target){
result.push_back(i+1);
result.push_back(j+1);
return result;
}
else if(numbers[i]+numbers[j]<target)
i++;
else
j--;
}
throw invalid_argument("no solution");
}
//167 的二分查找实现
vector<int> twoSum2(vector<int>& numbers, int target) {
int length=numbers.size();
int i = 0;
int mid=0;
for(i; i< length;i++){
int num2=target-numbers[i];
int l=i+1,r=length-1;//刚开始我把l=i;导致错误
while(l<=r){
mid = l + (r-l)/2;
if( numbers[mid] == num2 ){
//刚开始我这里写的是break,把下面四行写在了while外面,报错
vector<int> vec;
vec.push_back(i+1);
vec.push_back(mid+1);
return vec;
}
if( numbers[mid] < num2 )
l = mid + 1;
else
r = mid - 1;
}
}
}
//125. Valid Palindrome
//只看数字和字母,忽略大小写的情况下,检查是否回文
//c++ string类中 isalnum,toupper太好用啦
bool isPalindrome(string s) {
int i=0;
int j=s.size()-1;
for(;i<j;i++,j--){
while(isalnum(s[i])==false&&i<j)i++;
while(isalnum(s[j])==false&&i<j)j--;
if(toupper(s[i])!=toupper(s[j]))
return false;
}
return true;
}
//344翻转字符串
string reverseString(string s) {
int i=0;
int j=s.size()-1;
while(i<j){
swap(s[i++],s[j--]);
}
return s;
}
//345,找到字符串中的元音字母,然后翻转位置
string reverseVowels(string s) {
int i = 0;
int j = s.size()-1;
while(i<j){
i=s.find_first_of("aeiouAEIOU",i);//从s的第i个位置开始往后寻找"aeiouAEIOU"里面的任意一个字符
j=s.find_last_of("aeiouAEIOU",j);//从s的第j个位置开始往前寻找"aeiouAEIOU"里面的任意一个字符
if(i<j)//我忘记写这句话了
swap(s[i++],s[j++]);
}
return s;
}
//11 给一个数组height,从中任选两项 i 和 j(i <= j),
//min(height[i], height[j]) * (j - i) 最大化,求解这个最大值。
//考虑改变枚举容器的顺序,首先看编号为0和n-1的两条边组成的容器,令其为当前最优解。
//不妨设height[0] < height[n-1],那么所有左边界为0的容器一定都比当前最优解要差(水的高度相同但是宽度变小),
//于是可以忽略这样的方案。所以问题规模缩小了1(变为在编号为1..n-1的边中找两条边来组成容器),依次类推,
//每次将问题的规模缩小1,最后只需要统计O(n)个容器的最优解即可。(最优化剪枝)
int maxArea(vector<int>& height) {
int i=0;
int j=height.size()-1;
int area=0;
while(i<j){
area=max(area,min(height[i],height[j])*(j-i));
if(height[i]<height[j])
i++;
else
j--;
}
return area;
}
打开App,阅读手记