344.反转字符串
思路:利用双指针法,收尾交换。
class Solution {
public:
void reverseString(vector<char>& s) {
for(int i =0;i<s.size();i++)
{
int j = s.size()-1-i;
if(i>=j)
{
break;
}
char temp = s[i];
s[i]=s[j];
s[j] =temp;
}
}
};
541. 反转字符串II
思路:每操作2k个字符,操作一次,因此在循环中直接i+=2*k;在循环内部,判断剩余字符数与k的关系,只要大于等于k个,就翻转前k个字符,如果小于k个,就全部翻转。i+k比size小,说明最后剩余的元素在k~2k之间,如果比size大,说明最后剩余的小于k个,需要全部翻转。
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]);
}
}
string reverseStr(string s, int k) {
for(int i =0;i<s.size();i+=2*k)
{
if(i+k<=s.size())
{
reverse(s,i,i+k-1);
}
else
{
reverse(s,i,s.size()-1);
}
}
return s;
}
};
卡码网:54.替换数字
思路:首先判断字符串中有多少个数字,每有1个数字,新字符串的长度应该比原来字符串的长度+5,因为数字变成了number,然后从后往前循环数组,当遇到数字时,就用number代替,一个一个输入,必须是从后往前循环,从前往后循环会覆盖掉原字符串的元素。
#include<iostream>
using namespace std;
int main()
{
string input;
cin>>input;
int count = 0;
int oldSize = input.size();
for(int i =0;i < input.size();i++)
{
if(input[i]>='0'&&input[i]<='9')
{
count++;
}
}
input.resize(input.size()+count*5);
int newSize = input.size();
for(int i = oldSize-1,j = newSize-1;i>=0;i--,j--)
{
if(input[i]>='0'&&input[i]<='9')
{
input[j] = 'r';
input[j - 1] = 'e';
input[j - 2] = 'b';
input[j - 3] = 'm';
input[j - 4] = 'u';
input[j - 5] = 'n';
j -= 5;
}
else
{
input[j] = input[i];
}
}
cout<<input;
system("pause");
return 0;
}
151.翻转字符串里的单词
思路:需要两个函数,第一个函数的作用为删除空格,第二个函数为翻转,首先删除空格,三种情况,即空格在头部、尾部和中部,用快慢指针来消除空格,如果空格在头部,快指针后移,慢指针不同,当快指针指向非空格处时,将字符赋给满指针;当经过一个完整的单词后,快指针又会重新指向空格,此时快指针继续后移,慢指针不动,这样相当于消除了中部的空格,但单词之间还需要有一个空格间隔,因此当快指针再次指向非空格处时,慢指针先赋一个空格再后移,再将单词输入。注意在删除空格后, 字符串要返回新的长度。
所以,思路总结为,先删除所有的空格,同时在单词间隔处加入一个空格,然后将整个字符串全部翻转,然后再将逐个单词翻转,恢复正常顺序。
class Solution {
public:
void change(string &s,int start,int end)
{
for(int i=start,j=end;i<j;i++,j--)
{
swap(s[i],s[j]);
}
}
void removespace(string &s)
{
int slowindex=0;
for(int i =0;i<s.size();i++)
{
if(s[i]!=' ')
{
if(slowindex!=0)
{
s[slowindex++] =' ';
}
while(i<s.size() && s[i]!=' ')
{
s[slowindex++] = s[i++];
}
}
}
s.resize(slowindex);
}
string reverseWords(string s) {
//删除空格
removespace(s);
//交换位置
change(s,0,s.size()-1);
int start = 0;
for(int i =0;i<=s.size();i++)
{
if(s[i]==' '||i==s.size())
{
change(s,start,i-1);
start = i+1;
}
}
return s;
}
};
卡码网:55.右旋转字符串
思路:写一个翻转的函数,先将整个字符串翻转,再分别翻转前k个字符,和后续字符,恢复正常顺序。
#include<iostream>
using namespace std;
void change(string &s,int start,int end)
{
for(int i =start,j=end;i<j;i++,j--)
{
swap(s[i],s[j]);
}
}
int main()
{
string s;
int k;
cin>>k;
cin>>s;
change(s,0,s.size()-1);
change(s,0,k-1);
change(s,k,s.size()-1);
cout<<s;
system("pause");
return 0;
}
收获:
1、学会了字符串翻转的思想。
2、再处理字符串的时候,字符串的长度发生改变,要及时resize。
3、当需要字符串前后交换位置时,可以先整个翻转,再逐段翻转回去。