LeetCode344.反转字符串
思路:双指针法。
C++代码如下:
class Solution
{
public:
void reverseString(vector<char>& s)
{
for(int i = 0, j = s.size()-1; i < j; i++,j--)
{
char tmp = s[i];
s[i] = s[j];
s[j] = tmp;
}
}
};
LeetCode541.反转字符串II
思路:分为两种情况:1.每隔2k个字符的前k个字符进行反转;剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符;2.剩余字符少于 k 个,则全部反转。按照这两种情况分别处理。
C++代码如下:
class Solution
{
public:
string reverseStr(string s, int k)
{
int m = 0, n = 0;
for(int i = 0; i < s.size(); i += 2*k)
{
if(i+k <=s.size()) //1.每隔2k个字符的前k个字符进行反转
{ //2.剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符
for(m = i, n = i+k-1; m < n; m++,n--)
{
char tmp = s[m];
s[m] = s[n];
s[n] = tmp;
}
}
else if(i+k > s.size()) //3.剩余字符少于 k 个,则全部反转。
{
for(m = i, n = s.size()-1; m < n; m++,n--)
{
char tmp = s[m];
s[m] = s[n];
s[n] = tmp;
}
}
}
return s;
}
};
剑指Offer05.替换空格
思路:数组扩充到每个空格替换成"%20"之后的大小。再使用双指针法从后向前填充元素。
C++代码如下:
class Solution
{
public:
string replaceSpace(string s)
{
int count = 0;
//遍历一遍,看下有几个空格
for(int i = 0; i< s.size(); i++)
{
if(s[i] == ' ')
{
count++;
}
}
//k个空格,扩展2k长度
int old_size = s.size();
s.resize(old_size + 2*count);
//字符向后移动
int i = 0, j = 0;
for(i = old_size-1,j = s.size() - 1; i >=0 ;)
{
if(s[i] != ' ')
{
s[j] = s[i];
i--;
j--;
}
else
{
s[j] = '0';
s[j-1] = '2';
s[j-2] = '%';
j -= 3;
i--;
}
}
return s;
}
};
LeetCode151.翻转字符串里的单词
思路:总体思路是先去除掉原字符串的冗余空格,再把整个字符串翻转过来,然后再把每个单词翻转过来。其中去除冗余空格又分为去除开始的空格,以及中间的重复空格,和去除尾部的空格。总体难度不大。
C++代码如下:
class Solution
{
public:
//1.去除冗余空格,去除开始和结尾的空格
void removeExtraSpaces(string& s)
{
int fastIndex = 0;
int slowIndex = 0;
int Old_size = s.size();
//去除开始的空格
while(s[fastIndex] == ' ')
{
fastIndex++;
}
//去除中间的重复空格
for(; fastIndex < Old_size; fastIndex++)
{
if((fastIndex-1>0) && (s[fastIndex]==s[fastIndex-1]) && (s[fastIndex] == ' ')) //遇到重复空格
{
continue;
}
else
{
s[slowIndex] = s[fastIndex];
slowIndex++;
}
}
//去除尾部的空格
if(slowIndex - 1 > 0 && s[slowIndex - 1] == ' ')
{
s.resize(slowIndex - 1);
}
else
{
s.resize(slowIndex);
}
}
//2.整个字符串翻转(2和3步骤顺序调换也可以)
void reverse(string& s)
{
for(int i = 0, j = s.size()-1; i < j; i++, j--)
{
swap(s[i],s[j]);
}
}
//3.每个单词翻转
string reverseWords(string s)
{
removeExtraSpaces(s);
reverse(s);
int p = 0;
int q = 0;
int tmp = -1;
for(int i = 0; i < s.size(); i++)
{
if(s[i] == ' ') //遇到空格
{
int m = i-1; //m为当前单词的最后一位
for(p = tmp + 1, q = m; p < q; p++,q--)
{
int tmp_val = s[p];
s[p] = s[q];
s[q] = tmp_val;
}
tmp = i;
}
if(i == s.size()-1)
{
for(p = tmp + 1, q = i; p < q; p++,q--)
{
int tmp_val = s[p];
s[p] = s[q];
s[q] = tmp_val;
}
}
}
return s;
}
};
注意的地方:
以下写法,会报错,说是数组越界的意思。因为我还没判断fastIndex-1>0,就直接判断s[fastIndex]==s[fastIndex-1]是否成立,有可能s[fastIndex]==s[fastIndex-1]成立但是它们的前提条件fastIndex-1>0并不成立,所以会数组越界。
if((s[fastIndex]==s[fastIndex-1]) && (fastIndex-1>0) && (s[fastIndex] == ' ')) //遇到重复空格
{
continue;
}
修改为:先判断fastIndex-1>0再判断s[fastIndex]==s[fastIndex-1]就不会报错了。如下:
if((fastIndex-1>0) && (s[fastIndex]==s[fastIndex-1]) && (s[fastIndex] == ' ')) //遇到重复空格
{
continue;
}
剑指Offer58-II.左旋转字符串
思路:先反转0k-1的字符串,再反转ks.size()-1的字符串,最后反转整个字符串即可。
C++代码如下:
class Solution
{
public:
string reverseLeftWords(string s, int n)
{
//1.反转0~k-1的字符串;反转k~s.size()-1的字符串
for(int i = 0, j = n-1; i<j; i++,j--)
{
char tmp = s[i];
s[i] = s[j];
s[j] = tmp;
}
for(int i = n,j = s.size()-1; i<j; i++,j--)
{
char tmp = s[i];
s[i] = s[j];
s[j] = tmp;
}
//2.反转整个字符串
for(int i = 0,j = s.size()-1; i < j; i++, j--)
{
char tmp = s[i];
s[i] = s[j];
s[j] = tmp;
}
return s;
}
};