344.反转字符串
思路:一眼双指针
问题:为啥双指针这么快了都才打败58%的人??????????
class Solution {
public:
void reverseString(vector<char>& s) {
//思路:哈哈直接双指针
int right=s.size()-1;
for(int i=0;i<right;i++)
{
char mid=s[i];
s[i]=s[right];
s[right]=mid;
right--;
}
}
};
二刷:双指针
class Solution {
public:
void reverseString(vector<char>& s) {
int n=s.size();
int left=0,right=n-1;
while(left<right){
int temp=s[left];
s[left++]=s[right];
s[right--]=temp;
}
}
};
541.反转字符串II
思路:一次遍历,使用双指针,初始化right=k-1,left=0;先把第一个k反转;当i-right==2k时,
记录right=i,left+=2*k;
然后把这个区间内的单词反转
分析:剩余字符小于k时要全部反转,剩余字符大于k小于2*k时反转k;s长度小于2*k时要考虑
!!!剩余字符数大于k小于2*k在遍历中无需考虑。
class Solution {
public:
void judge(string&s,int left,int right)
{
while(left<right)//使用双指针直接反转区间内字符
{
char temp=s[left];
s[left]=s[right];
s[right]=temp;
right--;
left++;
}
}
string reverseStr(string s, int k) {
int n=s.size();
if(n<=2*k)//当s长度小于2*k时
{
if(n<k)
judge(s,0,n-1);
else
judge(s,0,k-1);
return s;
}
int left=0,right=k-1;
judge(s,left,right);//先把前k个单词反转
for(int i=0;i<n;i++)
{
if(i-right==2*k)//每次遍历到需要反转的右区间时
{
right=i;
left+=2*k;
judge(s,left,right);
}
if(i==n-1)//遍历到最后一位时
{
if(i-right<2*k)//还没有遍历到反转区间的右区间时
{
left+=2*k;
right=i;
judge(s,left,right);
}
}
}
return s;
}
};
二刷:同样的思路,判断区间,字符翻转
class Solution {
public:
void restrs(string& mid,int start,int end){
end--;
while(start<end){
int temp=mid[start];
mid[start++]=mid[end];
mid[end--]=temp;
}
}
string reverseStr(string s, int k) {
int n=s.size();
int start=0;
while(start<n){
int mid=start+k;
if(n<mid) restrs(s,start,n); //往后k个数超出范围
else{//往后k个数没超出范围
restrs(s,start,mid);
start+=k;
}
start+=k;
}
return s;
}
};
剑指Offer 05.替换空格
分析:本来想直接替换,但是%20是多位字符,无法直接替换,插入的话后面的字符都要向后移动,相当于增加了时间复杂度。
思路一:使用额外空间复制
class Solution {
public:
string replaceSpace(string s) {
string mid="%20",result="";
for(int i=0;i<s.size();i++)
{
if(s[i]==' ')
result+=mid;
else
result+=s[i];
}
return result;
}
};
思路二:不使用额外空间,直接在字符串尾上添加复制
class Solution {
public:
string replaceSpace(string s) {
char mids[3]={'%','2','0'};
int count=0;
for(int i=0;i<s.size();i++)//查找字符串中空格数
{
if(s[i]==' ')
count++;
}
int oldsize=s.size();//原来的长度
s.resize(s.size()+count*2);//一个空格换为三个字符,每个需要增加两个字符
int newsize=s.size();//增加后的长度
int front=oldsize-1,last=newsize-1;
while(front>=0)
{
if(s[front]!=' ')//当扫描到字符时,直接把字符替换到后面
{
s[last]=s[front];
}
else{//当扫描到空格时,开始用字符填充
s[last]=mids[2];
s[--last]=mids[1];
s[--last]=mids[0];
}
last--;
front--;
}
return s;
}
};
二刷:双指针替换
class Solution {
public:
string replaceSpace(string s) {
int n=s.size();
int midcount=0;
for(auto it:s){
if(it==' ') midcount++;//计算空格数量
}
int count=midcount*2;//要加入字符的空间
s.resize(n+count);//增加空间
int pre=n-1,last=s.size()-1;
while(pre>=0){
if(s[pre]!=' ') s[last--]=s[pre];
else{//遍历到空格时
s[last--]='0';
s[last--]='2';
s[last--]='%';
}
pre--;
}
return s;
}
};
151.翻转字符串里的单词
思路一:本题做过多次,但是不知如何优化,
class Solution {
public:
string reverseWords(string s) {
//思路:倒着遍历,加入结果字符串
int n=s.size();
string result="",mid="";
for(int i=n-1;i>=0;i--)
{
if(s[i]!=' ')
{
mid=s[i]+mid;
if(i==0)
{
result+=mid;
}
}
else{
if(!mid.empty())
{
result+=mid+' ';
mid.clear();
}
}
}
if(result[result.size()-1]==' ')
result.erase(result.end()-1);
return result;
}
};
思路二:看了卡哥的题解是先去掉多余空格,再进行两次翻转,没有对字符串进行增删确实快很多!
二刷:先删除多余空格,然后整个字符串进行翻转,接着逐个字符串进行翻转
class Solution {
public:
void reverseWord(string &mid,int start,int end){//翻转字符串
while(start<end){
char temp=mid[start];
mid[start++]=mid[end];
mid[end--]=temp;
}
}
void deletek(string &mid){//删除多余空格
string str;
for(auto it:mid){//删除前面和中间的多余空格
if(str.empty() && it==' ') continue;
else if(!str.empty() && str.back()==' ' && it==' ') continue;
str.push_back(it);
}
while(str.back()==' ') str.pop_back();//去除尾巴空格
mid.clear();
mid=str;
}
string reverseWords(string s) {
deletek(s);//删除多余空格
reverseWord(s,0,s.size()-1);//翻转整个字符串
int n=s.size();
int left=0;
while(left<n){
int start=left;
while(left<n && s[left]!=' ') left++;//找到字符的尾巴
reverseWord(s,start,left-1);//翻转单个字符串
left++;
}
return s;
}
};
剑指Offer 58 - II.左旋字符串
class Solution {
public:
string reverseLeftWords(string s, int n) {
int m=s.size();
if(n>=m)
return s;
string mid="",result="";
for(int i=0;i<m;i++)
{
if(i<=n-1)
{
mid+=s[i];
}
else
result+=s[i];
}
result+=mid;
return result;
}
};
二刷:我真牛逼
class Solution {
public:
string reverseLeftWords(string s, int n) {
int len=s.size();
for(int i=0;i<n;i++) s.push_back(s[i]);
return s.substr(n);
}
};