《代码随想录》字符串部分
题目:反转字符串
class Solution {
public:
void reverseString(vector<char>& s) {
int left = 0;
int right = s.size() - 1;
while (left < right) {
swap(s[left], s[right]);
left++;
right--;
}
}
};
题目:反转字符串II
class Solution {
public:
void reverse(string &s, int left, int right) {
while (left < right) {
swap(s[left], s[right]);
left++;
right--;
}
}
string reverseStr(string s, int k) {
for (int i = 0; i < s.size(); i = i + 2 * k) {
if (i + k <= s.size()) {//反转这部分
reverse(s, i, i + k - 1);
} else {//i + k如果大于size了,那就是反转从i到最后
reverse(s, i, s.size() - 1);
}
}
return s;
}
};
题目:替换空格为%20(数组变长,复习数组变短的操作)
class Solution {
public:
string replaceSpace(string s) {
//先遍历一次s,确定有几个空格
int count = 0;
for (char ss : s) {
if (ss == ' ') {
count++;
}
}
//记录下来现在的最后一个的位置,不然一会resize了找不到了
int index1 = s.size() - 1;
//根据几个空格才知道resize成多大的空间
s.resize(s.size() + count * 2);
//双指针,从后往前遍历(因为这是数组变长,如果数组变短,即删除数组元素那个题,那就是从前往后遍历)
int index2 = s.size() - 1;
while (index1 < index2) {
if (s[index1] != ' ') {
s[index2--] = s[index1--];
} else {
s[index2--] = '0';
s[index2--] = '2';
s[index2--] = '%';
index1--;
}
}
return s;
}
};
题目:反转字符串中的单词
这个题目时很好的,特别是加了去除多余的空格,这部分函数其实是《移除数组元素》的变体,充分考虑空格在不同的情况应该如何移除,是很好的题目
这道题目可以说是《移除数组元素》《反转字符串II》的结合
class Solution {
public:
//移除多余空格,这其实是数组变短的操作,数组怎么变短呢?其实就是双指针
void removeExtraSpace(string &s) {
int fast = 0;
int slow = 0;
//移除前面
while (fast < s.size()) {
if (s[fast] == ' ') {
fast++;
} else {
break;
}
}
//移除中间
while (fast < s.size()) {
if (s[fast] != ' ') {//遇到字母,直接搬运过去
s[slow++] = s[fast++];
} else if (s[fast] == ' ' && s[fast - 1] == ' ') {//遇到空格,第一个搬运过去,后面的只有fast走
fast++;
} else if (s[fast] == ' ' && s[fast - 1] != ' ') {//遇到第一个空格
s[slow++] = s[fast++];
}
}
//移除后面
if (s.back() == ' ') {
s.resize(slow - 1);
} else {
s.resize(slow);
}
}
string reverseWords(string s) {
//先去除多余的空格
removeExtraSpace(s);
//整个反转
reverse(s.begin(), s.end());
int index = 0;
for (int i = 0; i <= s.size(); i++) {
if (i == s.size()) {//i已经到了最后
reverse(s.begin() + index, s.end());
}
if (s[i] == ' ') {//i到了空格
reverse(s.begin() + index, s.begin() + i);
index = i + 1;
}
}
return s;
}
};
注意:
严格来说,最后的循环其实是下面这个,下面这个写的才是长常规的,上面那个写的不是很常规
int index = 0;
for (int i = 0; i < s.size(); i++) {
if (i == s.size() - 1) {//i已经到了最后
reverse(s.begin() + index, s.end());
}
if (s[i] == ' ') {//i到了空格
reverse(s.begin() + index, s.begin() + i);
index = i + 1;
}
}
题目:左旋转字符串
class Solution {
public:
//这个的思路很好想,先把前k个反转,再把后面的也反转,最后再总的反转一遍
//标准的反转字符串的函数
void reverse(string &s, int left, int right) {
while (left < right) {
swap(s[left], s[right]);
left++;
right--;
}
}
string reverseLeftWords(string s, int n) {
reverse(s, 0, n - 1);//先反转前K个字符
reverse(s, n, s.size() - 1);//再反转后面的那部分
reverse(s, 0, s.size() - 1);//再整体反转一次
return s;
}
};