代码随想录训练营 Day 08 :字符串
344. 反转字符串
题目
解题
数组、链表、字符串等的原地反转,大多可使用双指针法解决
code
class Solution {
public:
void reverseString(vector<char>& s) {
int len = s.size();
int left = 0, right = len -1;
while(left <= right)
{
char tmp = s[right];
s[right] = s[left];
s[left] = tmp;
left ++;
right --;
}
}
};
541. 反转字符串 II
题目
解题
重点在于将字符串依据长度分区,然后分别进行不同的操作。
code
class Solution {
public:
string reverseStr(string s, int k) {
int i = 0;
for(int i = 0; i < s.size(); i += 2 * k)
{
//区间长度=2k
if((i + 2 * k) <= s.size() )
reverse(s.begin() + i, s.begin() + i + k);
// 区间长度< 2k, 即末尾
else{
int tmp = k > s.size() - i ? s.size() - i : k;
reverse(s.begin() + i, s.begin() + i + tmp);
}
}
return s;
}
};
总结
注意vector、string等的使用差异
剑指 Offer 05. 替换空格
题目
解题
寻找空格,然后替换。一个难点在于,空格只是一个字符,而要替换的是一个小字符串,两者大小不一致,因此这实际上是一个填充问题。
数组填充问题关键有两点:第一,扩容(resize());第二,从后向前 顺次填充
code
class Solution {
public:
string replaceSpace(string s) {
int i, len = s.size(), nlen = len;
// 扩容
for(i = 0; i < s.size(); i++)
{
if(s[i] == ' ')
nlen += 2;
}
s.resize(nlen);
// 填充
for(i = len - 1; i >= 0; i--)
{
if(s[i] != ' ')
s[--nlen] = s[i];
else
{
s[--nlen] = '0';
s[--nlen] = '2';
s[--nlen] = '%';
}
}
return s;
}
};
151. 反转字符串中的单词
题目
解题
三步法
1、删除空格
对空格掐头去尾再中间;不需要删除的,则顺序保留
2、全局反转
对已删除空格的新字符串反转,可以颠倒单词顺序,但同时,单词内部字母顺序也被颠倒
3、单词内部顺序回正
所以,第三步就是对每个单词内部的字母再次颠倒,从而回正
code
class Solution {
public:
void reverse(string &s, int start, int end){
int i = start, j = end;
while(i <= j){
swap(s[i], s[j]);
i++;
j--;
}
}
string reverseWords(string s) {
int len = s.size();
int start = 0, end = len - 1, j = 0;
//先删去头尾的空格
while(s[start] == ' ')
start++;
while(s[end] == ' ')
end --;
for(int i = start; i <= end; i++)
{
//删去中间的空格
if(s[i] == ' ' && s[i] == s[i - 1])
continue;
else
s[j++] = s[i];
}
s.resize(j);
// 全局反转
reverse(s, 0, s.size() - 1);
// 单词内部顺序回正
start = 0;
end = 0;
while(end <= s.size()){
if(end <s.size() && s[end] != ' ')
end ++;
else{
reverse(s, start, end - 1);
end = end + 1;
start = end;
}
}
return s;
}
};
总结
明确空格删除的条件很关键
剑指 Offer 58 - II. 左旋转字符串
题目
解题
先全局反转,然后两侧分别反转
或
先两侧反转,再全局反转
code
class Solution {
public:
void reverse(string &s, int start, int end){
int i = start, j = end;
while(i <= j){
swap(s[i], s[j]);
i++;
j--;
}
}
string reverseLeftWords(string s, int n) {
reverse(s, 0, s.size() - 1);
reverse(s, 0, s.size() - n - 1);
reverse(s, s.size() - n , s.size() - 1);
return s;
}
};