Leetcode 344.反转字符串
题目链接:344 反转字符串
题干:编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
- 你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。
思考:两指针分别指向字符串的首部字符和尾部字符,交换两字符位置后收缩指针,直到处理到中间位置
代码:
class Solution {
public:
void reverseString(vector<char>& s) {
for (int i = 0, j = s.size() - 1; i < s.size() / 2; i++,j--) {
swap(s[i],s[j]);
}
}
};
Leetcode 541. 反转字符串II
题目链接:541 反转字符串II
题干:给定一个字符串 s 和一个整数 k,从字符串开头算起, 每计数至 2k 个字符,就反转这 2k 个字符中的前 k 个字符。
- 如果剩余字符少于 k 个,则将剩余字符全部反转。
- 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
思考:以2k为单位处理,每个单位够k个时将前k个字符反转,字符串最后一个单位不够k个时则整个单位反转
代码:
class Solution {
public:
string reverseStr(string s, int k) {
for (int i = 0; i < s.size(); i += 2 * k) { //2k为单位处理
if (i + k <= s.size()) //凑足k个
reverse(s.begin() + i, s.begin() + i + k);
else
reverse(s.begin() + i, s.end());
}
return s;
}
};
卡码网 54.替换数字
题目链接:54 替换数字
题干:给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。
- 1 <= s.length < 10000
思考:先统计数字个数扩容字符串大小,再从后往前处理非数字直接赋值,数字则替换存储
代码:
#include<iostream>
using namespace std;
int main() {
string s;
while (cin >> s) {
int count = 0; // 统计数字的个数
int sOldSize = s.size();
for (int i = 0; i < s.size(); i++) {
if (s[i] >= '0' && s[i] <= '9') {
count++;
}
}
// 扩充字符串s的大小,也就是每个空格替换成"number"之后的大小
s.resize(s.size() + count * 5);
int sNewSize = s.size();
// 从后先前将空格替换为"number"
for (int i = sNewSize - 1, j = sOldSize - 1; j < i; i--, j--) {
if (s[j] > '9' || s[j] < '0') {
s[i] = s[j];
} else {
s[i] = 'r';
s[i - 1] = 'e';
s[i - 2] = 'b';
s[i - 3] = 'm';
s[i - 4] = 'u';
s[i - 5] = 'n';
i -= 5;
}
}
cout << s << endl;
}
}
Leetcode 151.翻转字符串里的单词
题目链接:151 翻转字符串里的单词
题干:给你一个字符串
s
,请你反转字符串中 单词 的顺序。
- 单词 是由非空格字符组成的字符串。
s
中使用至少一个空格将字符串中的 单词 分隔开。- 返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
- 输入字符串
s
中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。s
包含英文大小写字母、数字和空格' ';
s
中 至少存在一个 单词
思考:整体思路:先处理字符串关于空格的格式,再将字符串整体反转,最后将每个单词逐个反转
- 处理字符串空格格式使用双指针法,慢指针指向存储位置,快指针寻找非空字符,将每个非空字符存储到慢指针的位置,每处理完一个单词再存储一个空格
- 反转字符串,同上344题
代码:
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]);
}
}
//控制字符串含空格的格式
void removeExtraSpaces(string& s) {
int slow = 0,fast = 0;
for (; fast < s.size(); fast++) {
if (s[fast] != ' ') { //只处理非空字符
if (slow != 0) //手动控制空格
s[slow++] = ' ';
while (fast < s.size() && s[fast] != ' ') //将每个单词完整处理
s[slow++] = s[fast++];
}
}
s.resize(slow);
}
string reverseWords(string s) {
removeExtraSpaces(s);
reverse(s,0,s.size() - 1); //将整个字符串反转一次
int slow = 0,fast = 0;
for (; fast < s.size(); fast++) {
while (fast < s.size() && s[fast] != ' ')
fast++;
reverse(s,slow,fast - 1);
fast++;
slow = fast;
}
return s;
}
};
卡码网 55.右旋字符串
题目链接:55 右旋字符串
题干:字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k,请编写一个函数,将字符串中的后面 k 个字符移到字符串的前面,实现字符串的右旋转操作。
- 1 <= k < 10000, 1 <= s.length < 10000
思考:先将整体反转,再将以K分割成两个的子字符串分别反转(当然操作反过来也一样)
代码:
#include<iostream>
#include<algorithm>
using namespace std;
int main() {
int n;
string s;
cin >> n;
cin >> s;
int len = s.size(); //获取长度
reverse(s.begin(), s.end()); // 整体反转
reverse(s.begin(), s.begin() + n); // 先反转前一段,长度n
reverse(s.begin() + n, s.end()); // 再反转后一段
cout << s << endl;
}
自我总结:
反转字符串的思路改变;复习双指针法修改存储内容或存储格式