打卡第八天,今天是第四章字符串
今日任务
- 344.反转字符串
- 转字符串II
- 剑指Offer 05.替换空格
- 151.翻转字符串里的单词
- 剑指Offer58-II.左旋转字符串
344.反转字符串
我的题解
class Solution {
public:
void reverseString(vector<char>& s) {
int l = 0, r = s.size() - 1;
while(l < r) {
swap(s[l++], s[r--]);
}
}
};
利用左右俩双指针,交换元素,直到指针相遇。
代码随想录
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]);
}
}
};
541. 转字符串II
我的题解
class Solution {
public:
void reverse(string &s, int l, int r) {
while(l < r) {
swap(s[l++], s[r--]);
}
}
string reverseStr(string s, int k) {
int i = 0;
while(i < s.size()) {
int l = i, r = i + k <= s.size() ? i + k - 1 : s.size() - 1;
reverse(s, l, r);
i += 2 * k;
}
return s;
}
};
定义 i (从区间 (i, i + k - 1) 反转字符),注意每次循环 i += 2 * k,因为题目是每次在 2k 区间里面反转前 k 个
剑指Offer 05.替换空格
我的题解
暴力做法:
class Solution {
public:
string replaceSpace(string s) {
for(int i = 0; i < s.size(); i++) {
if(s[i] == ' ') {
s[i] = '%';
s.insert(i + 1, "20");
}
}
return s;
}
};
代码随想录
双指针做法
class Solution {
public:
string replaceSpace(string s) {
int cnt = 0;
int oldSize = s.size();
for(char c : s) {
if(c == ' ') {
cnt++;
}
}
int newSize = oldSize + cnt * 2;
s.resize(newSize);
for(int i = newSize - 1, j = oldSize - 1; j < i; i--, j--) {
if(s[j] == ' ') {
s[i] = '0';
s[i - 1] = '2';
s[i - 2] = '%';
i -= 2;
} else {
s[i] = s[j];
}
}
return s;
}
};
- 先字符串中计算空格个数 cnt。
- 将字符串长度增加 c n t ∗ 2 cnt * 2 cnt∗2。
- 定义指针 i 指向 新字符串尾部, j 指向原字符串尾部。
- 当 j 指向字符不等于空,直接将字符填充到 i 的位置; 当 j 指向字符为空,i 位置填充 “%20”,并向前移动。
为什么要从后向前填充,从前向后填充不行么?
从前向后填充就是O(n^2)的算法了,因为每次添加元素都要将添加元素之后的所有元素向后移动。
151.翻转字符串里的单词
题解
class Solution {
public:
void reverse(string &s, int l, int r) {
while(s[r] == ' ') r--;
while(l < r) {
swap(s[l++], s[r--]);
}
}
string reverseWords(string s) {
int slow = 0;
for(int i = 0; i < s.size(); i++) {
if(s[i] != ' ') {
if(slow != 0) s[slow++] = ' ';
while(i < s.size() && s[i] != ' ')
s[slow++] = s[i++];
}
}
s.resize(slow);
reverse(s, 0, s.size() - 1);
for(int i = 0, j = 0; i <= s.size(); i ++) {
if(s[i] == ' ' || i == s.size()) {
reverse(s, j, i - 1);
j = i + 1;
}
}
return s;
}
};
- 第一步先除去多余的空格
- 第二步,翻转整个字符串
- 第三步,翻转单个单词
剑指Offer58-II.左旋转字符串
我的题解
方法一
class Solution {
public:
string reverseLeftWords(string s, int n) {
int oldsize = s.size();
s = s + s;
int slow = 0;
for(int i = n; slow < oldsize; i++) {
s[slow++] = s[i];
}
s.resize(oldsize);
return s;
}
};
方法二
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;
}
};