代码随想录 day8 第四章 字符串
344.反转字符串
leetcode链接
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
- 思路:双指针
输入:s = [“h”,“e”,“l”,“l”,“o”]
输出:[“o”,“l”,“l”,“e”,“h”]
class Solution {
public:
void reverseString(vector<char>& s) {
for (int i = 0, j = s.size() - 1; i < s.size()/2; i++,j--){
int temp = s[i];
s[i] = s[j];
s[j] = temp;
}
}
};
541. 反转字符串II
leetcode链接
给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
输入:s = “abcdefg”, k = 2
输出:“bacdfeg”
- 思路:想着用双指针法 + swap,尤其对“剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,”,思路想复杂了
- 看的题解,
class Solution {
public:
string reverseStr(string s, int k) {
for (int i = 0; i < s.size(); i += (2*k)) {
// 1. 每隔 2k 个字符的前 k 个字符进行反转
// 2. 剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符
if (i + k <= s.size()) {
reverse(s.begin() + i, s.begin() + i + k );
}else {
// 3. 剩余字符少于 k 个,则将剩余字符全部反转。
reverse(s.begin() + i, s.end());
}
}
return s;
}
};
剑指Offer 05.替换空格
leetcode链接
请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
输入:s = “We are happy.”
输出:“We%20are%20happy.”
- 思路:将数组扩充至每个空格替换成“%20”之后的大小,采用双指针法,从后向前替换空格。i 指针指向旧字符串的末尾,j 指针指向新字符串的末尾。
class Solution {
public:
string replaceSpace(string s) {
int oldS = s.size();
int spaces = 0;
for (int t = 0; t < oldS; t++) {
if (s[t] == ' ') {
spaces++;
}
}
s.resize(s.size() + spaces*2);//扩充数组
int newS = s.size();
for (int i = oldS - 1, j = newS - 1; i < j;) {
if (s[i] != ' ') {
s[j] = s[i];
i--;
j--;
} else{
s[j] = '0';
s[j - 1] = '2';
s[j - 2] = '%';
i--;
j -= 3;
}
}
return s;
}
};
151.翻转字符串里的单词
leetcode链接
给你一个字符串 s ,请你反转字符串中 单词 的顺序。
单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。
返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。
输入:s = “the sky is blue”
输出:“blue is sky the”
- 自己的思路:先将整个字符串反转(双指针),然后以空格为分界符,将单词再反转。
- 自己思路的错误:思考不充分(空格删除部分),没有分功能编写(删除空格,字符串反转)
- 原题解:
- 移除多余空格(字符串前的空格、字符串中的多余空格、字符串后的空格)
- 整个字符串反转
- 将每个单词反转
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 reverseExtraSpace(string& s) {
int slowIndex = 0, fastIndex = 0;
//移除字符串前面的空格;
while (s.size() > 0 && fastIndex < s.size() && s[fastIndex] == ' ') {
fastIndex++;
}
//移除字符串中间的空格;
for ( ;fastIndex < s.size(); fastIndex++) {
if (fastIndex - 1 > 0
&& s[fastIndex - 1] == s[fastIndex]
&& s[fastIndex] == ' ') {
continue;
}else {
s[slowIndex++] = s[fastIndex];
}
}
//去掉字符串末尾的空格
if (slowIndex - 1 > 0 && s[slowIndex - 1] == ' ') {
s.resize(slowIndex - 1);
} else {
s.resize(slowIndex); // 重新设置字符串大小
}
}
string reverseWords(string s) {
reverseExtraSpace(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;
}
};
剑指Offer58-II.左旋转字符串
leetcode链接
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。
输入: s = “abcdefg”, k = 2
输出: “cdefgab”
- 思路:
- 反转区间为前n的子串;
- 反转区间为n到末尾的子串;
- 反转整个字符串;
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;
}
};