反转字符串
这道题我们使用双指针法,一个指针指向首元素,一个指针指向末尾元素,相互交换数值,然后首指针加1,末尾指针减1,继续交换。
class Solution {
public:
void reverseString(vector<char>& s) {
for(int i = 0,j = s.size()-1;i < j;i++,j--){
swap(s[i],s[j]);
}
}
};
反转字符串II![](https://img-blog.csdnimg.cn/c0e2e202c1ae4a3c8367c540cbbb999a.png)
这道题相较于前面一题有点难度,我们需要首先反转2k个字符中k个元素,然后又过2k个继续反转k个元素,直到剩余字符小于k个或者2k个。因为我们每次是隔着2k个,因此遍历函数的时候,我们使用i++过于繁琐,我们可以直接使用i += (2*k)。只要当前最后字符的剩余字符大于等于k,那么我们就可以直接反转k个元素。因此前2k个元素和最后一组数据可以组合起来,若是最后剩余字符小于k,直接反转里面有的元素就可以。
class Solution {
public:
string reverseStr(string s, int k) {
for(int i = 0;i < s.size();i += (2*k))
{
if(i + k <= s.size()){
reverse(s.begin()+i,s.begin()+i+k);
}else{
reverse(s.begin()+i,s.end());
}
}
return s;
}
};
替换空格
首先这道题,我们将字符串中每个空格都替换成%20,我们需要在不开辟新的辅助空间的情况下我们需要扩充数组的长度。这道题我们使用双指针法,用一个指针i指向原始长度的末尾,用另一个指针j指向新长度的末尾。我们预先留出扩充好的数组的长度,从后往前填充。
这里不使用从前往后填充,就是因每一次数组的长度都会变化。
class Solution {
public:
string replaceSpace(string s) {
int count = 0;
int sOldSize = s.size();
for(int i = 0;i < s.size();i++){
if(s[i] == ' '){
count++;
}
}
s.resize(s.size() + (2*count));
int sNewSize = s.size();
for(int j = sOldSize-1,i = sNewSize-1;j<i;i--,j--)
{
if(s[j] != ' ')
{
s[i] = s[j];
}else
{
s[i] = '0';
s[i-1] = '2';
s[i-2] = '%';
i -= 2;
}
}
return s;
}
};
只要j的位置上不为空,那么就把j位置上的那个数放到i位置上,如果为空,那就让i的前三位都补充上%20。
翻转字符串里的单词
这道题我们不增加额外空间,基本处理思路是:先移除多余的空格元素、然后再将整个字符串进行反转、然后将每个单词进行反转。
class Solution {
public:
void reverseExtraSpaces(string& s){
int slow = 0;
for(int i = 0;i < s.size();i++)
{
if(s[i] != ' ')//只有当i不指向空格才能接下来操作
{
if(slow != 0)//第一个单词前面不要空格,在接下来的每一个单词前面都加上一个空格
{
s[slow] = ' ';
slow++;
}
}
while(i < s.size() && s[i] != ' ')//补全每个单词,遇到下一个空格,就说明单词结束
{
s[slow] = s[i];
i++;
slow++;
}
}
s.resize(slow);//重新设置字符串长度
}
void reverse(string& s,int start,int end)
{
for(int i = start,j = end;i < j;i++,j--)
{
swap(s[i],s[j]);
}
}
string reverseWords(string s) {
reverseExtraSpaces(s);
reverse(s,0,s.size()-1);
int start = 0;
for(int i = 0;i <= s.size();i++)
{
if(i == s.size() || s[i] == ' ')
{
reverse(s,start,i-1);
start = i + 1;
}
}
return s;
}
};
左旋转字符串
这道题和前面一道题很类似,基本的解题思路是:我们先反转前区间前n个子串,再反转后面剩下的子串,最后再反转整个串。举个例子来说,abcdefg,n=2,先反转前两,就变成bacdefg,再反转后面5个就变成bagfedc,最后整体反转就是cdefgadb,这样以来就完成了我们的操作。
class Solution {
public:
string reverseLeftWords(string s, int n) {
reverse(s.begin(),s.begin()+n);
reverse(s.begin()+n,s.end());
reverse(s.begin(),s.end());
return s;
}
};