本题重点在于不使用额外的存储空间,故选择头尾指针进行交换达到反转的作用。
具体代码如下:
class Solution {
public:
void reverseString(vector<char>& s) {
int i=0;
int j=s.size()-1;
if(s.size()==1)
{
return;
}
while(i<j)
{
char tmp=s[i];
s[i]=s[j];
s[j]=tmp;
i++;
j--;
}
}
};
本题重点在于判断字符串剩余长度并分开表达,这里提供两种方法。
法一(不使用库函数):
class Solution {
public:
string reverseStr(string s, int k) {
int n=s.length();
int i=0;
while(n>0)
{
if(n<k)
{
int j=i;
int m=s.length()-1;
while(j<m)
{
swap(s[j],s[m]);
j++;
m--;
}
break;
}
else if(n>=k&&n<2*k)
{
int j=i;
int m=i+k-1;
while(j<m)
{
swap(s[j],s[m]);
j++;
m--;
}
break;
}
else
{
int j=i;
int m=i+k-1;
while(j<m)
{
swap(s[j],s[m]);
j++;
m--;
}
}
n-=2*k;
i+=2*k;
}
return s;
}
};
法二(使用库函数):
class Solution {
public:
string reverseStr(string s, int k) {
for(int i=0;i<s.length();i+=2*k)
{
if(i+k>s.length())
{
reverse(s.begin()+i,s.end());
}
else
{
reverse(s.begin()+i,s.begin()+i+k);
}
}
return s;
}
};
本题较为综合,要先将多余的空格处理掉,再将句子反转,而后将各个单词反转。处理空格时采用快慢指针法,慢指针指向的是处理完句子的末尾;句子反转与单词反转和上题中字符串反转类似。
具体代码如下:
class Solution {
public:
void reverse(string&s,int start,int end)
{
for(int i=start,j=end;i<j;i++,j--)
{
swap(s[i],s[j]);
}
}
void deleteextraspace(string&s)
{
int slow=0;
for(int fast=0;fast<s.length();fast++)
{
if(s[fast]!=' ')
{
if(slow!=0)
{
s[slow]=' ';
slow++;
}
while(s[fast]!=' '&&fast<s.length())
{
s[slow]=s[fast];
slow++;
fast++;
}
}
}
s.resize(slow);
}
string reverseWords(string s) {
deleteextraspace(s);
reverse(s,0,s.length()-1);
int start=0;
for(int i=0;i<=s.length();++i)
{
if(s[i]==' '||i==s.length())
{
reverse(s,start,i-1);
start=i+1;
}
}
return s;
}
};
四、卡码网第54题
本题重点在于扩容原字符串长度,而后通过双指针法,一个指向原字符串末尾,一个指向改变后字符串末尾,通过判断是否为数字进行字符的插入。
具体代码如下:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s;
while(cin>>s)
{
int count=0;
int oldsize=s.length();
for(int i=0;i<oldsize;i++)
{
if(s[i]>='0'&&s[i]<='9')
{
count++;
}
}
s.resize(oldsize+count*5);
int newsize=s.length();
for(int i=oldsize-1,j=newsize-1;i<j;i--,j--)
{
if(s[i]<'0'||s[i]>'9')
{
s[j]=s[i];
}
else
{
s[j]='r';
s[j-1]='e';
s[j-2]='b';
s[j-3]='m';
s[j-4]='u';
s[j-5]='n';
j-=5;
}
}
cout<<s<<endl;
}
}
五、卡码网第55题
本题重点在于移动字符到字符串头部,最初采用的是扩容字符串的方法与上题思路类似,将字符串后移后删除前面的空位置;后面采用先将字符串整体反转,再将两个部分分别反转的方法,降低了空间复杂度,下面给出这两个方法。
法一:
#include<iostream>
using namespace std;
int main()
{
int n;
string s;
cin>>n;
cin>>s;
int m=s.length();
s.resize(2*m-n);
int i=s.length()-1;
int j=m-n-1;
while(j>=0)
{
s[i]=s[j];
i--;
j--;
}
s.erase(0,m-n);
cout<<s<<endl;
}
法二:
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int n;
string s;
cin>>n;
cin>>s;
reverse(s.begin(),s.end());
reverse(s.begin(),s.begin()+n);
reverse(s.begin()+n,s.end());
cout<<s<<endl;
}