1.移除元素
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int i =0;
for(int j=0;j<nums.size();j++){
if(nums[j]!=val){
nums[i]=nums[j];
i++;
}
}
return i;
}
};
2.反转字符串
class Solution {
public:
void reverseString(vector<char>& s) {
int i =0;
int j= s.size()-1;
while(i<j){
char tmpc = s[i];
s[i]=s[j];
s[j]=tmpc;
i++;
j--;
}
}
};
3.翻转字符串里的单词
主要思路 :
1.先去除所有多余空格(先去首空格 然后 中间空格以及尾部保留一个即可,尾空格再次判断一下即可 最后通用resize从新改变字符串的长度)
void DeleleInvalidSpace(string &s){
// 去除首空格
int i =0;
int j= 0;
while(s[j]==' '){
j++;
}
for(;j<s.size();j++){
if(j-1>=0&&s[j]==s[j-1] && s[j]==' '){
continue;
}
s[i]=s[j];
i++;
}
// cout<<"xunhuan: "<<s<<endl;
// cout<<"i"<<i<<endl;
if(s[i-1]==' ') {
s.resize(i-1);
}else{
s.resize(i);
}
reverseWords(s,0,s.size()-1);
}
2.遍历翻转 遇见空格就翻转 但是最后单词是没有翻转的机会的 直接判断一下即可
// 最后一个单词也需要翻转
if(j==s.size()-1){
reverseWords(s,i,s.size()-1);
}
完整代码:
class Solution {
public:
void reverseWords(string &s,int i,int j) {
while(i<j){
// cout<<" i:"<<i<<"j:"<<j<<endl;
char temp = s[i];
s[i]=s[j];
s[j]=temp;
i++;
j--;
}
}
void DeleleInvalidSpace(string &s){
// 去除首空格
int i =0;
int j= 0;
while(s[j]==' '){
j++;
}
for(;j<s.size();j++){
if(j-1>=0&&s[j]==s[j-1] && s[j]==' '){
continue;
}
s[i]=s[j];
i++;
}
// cout<<"xunhuan: "<<s<<endl;
// cout<<"i"<<i<<endl;
if(s[i-1]==' ') {
s.resize(i-1);
}else{
s.resize(i);
}
reverseWords(s,0,s.size()-1);
}
string reverseWords(string s) {
DeleleInvalidSpace(s);
// cout<<"DeleleInvalidSpace:"<< s<<endl;
int i =0;
for(int j=0;j<s.size();j++){
if(s[j]==' '){
// cout<<"翻转之前"<<"i="<<i<<" j="<<j<<" 结果:"<<s<<endl;
reverseWords(s,i,j-1);
// cout<<"翻转之后"<<"i="<<i<<" j="<<j<<" 结果:"<<s<<endl;
cout<<endl;
i=j+1;
}
// 最后一个单词也需要翻转
if(j==s.size()-1){
reverseWords(s,i,s.size()-1);
}
}
return s;
}
};
4.实现 strStr()
见kmp章节
5.重复的子字符串
见kmp章节
补充题目:
6.有效三角形的个数
class Solution {
public:
int triangleNumber(vector<int>& nums) {
sort(nums.begin(),nums.end(),[](int a,int b){
return a<b;
});
int count =0;
for(int k=nums.size()-1;k>=0;k--){
int i=0;
int j= k-1;
while(i<j){
int sum = nums[i]+nums[j];
if(sum>nums[k]){
count=count+j-i;
j--;
}else{
i++;
}
}
}
return count;
}
};
7.三数之和
思路:首先排序 再先固定左边 然后从右边数组中从两头找和为target的元素
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(),nums.end(),[](int a,int b){
return a<b;
});
vector<vector<int>> res;
for(int i=0;i<nums.size();i++){
if(i-1>=0&&nums[i]==nums[i-1]){
continue;
}
int left =i+1;
int right = nums.size()-1;
int target = -nums[i];
while(left<right){
int sum = nums[left]+nums[right];
if(sum>target){
right--;
}else if(sum<target){
left++;
}else{
res.push_back({nums[i],nums[left],nums[right]});
while(left+1<nums.size()-1 &&nums[left]==nums[left+1]){
left++;
}
left++;
while( right-1>=0&&nums[right]==nums[right-1]){
right--;
}
right--;
}
}
}
return res;
}
};
二分法 注意下面的时间复杂度是 log(n)
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
if(nums.size()==0){
return {-1,-1};
}
int left =0;
int right = nums.size()-1;
while(left<right){
int mind = (left+right)/2;
if(nums[mind]>target){
right=mind -1;
}else if(nums[mind]<target){
left=mind+1;
}else{
right--;
}
}
if(nums[left]!=target){
return {-1,-1};
}
int zuo = left;
left =0;
right = nums.size()-1;
while(left<right){
int mind = (left+right+1)/2;
if(nums[mind]>target){
right=mind -1;
}else if(nums[mind]<target){
left=mind+1;
}else{
left++;
}
}
int you = left;
return {zuo,you};
}
};