今天进入字符串。第一题是反转字符串https://leetcode.cn/problems/reverse-string/description/,首先想到的是双指针一个left一个right,调用一下swap函数。比上一章哈希表简单一些。
class Solution {
public:
void reverseString(vector& s) {
int left = 0;
int right = s.size() - 1;
for(int i = 0; i < s.size(); i++){
if(left <= right){swap(s[left], s[right]);
left++;
right--;}
}
}
};
第二题还是反转字符串https://leetcode.cn/problems/reverse-string-ii/。有点卡住了,不知道怎么用swap对前k个进行反转。求助卡哥字符串基础操作! | LeetCode:344.反转字符串_哔哩哔哩_bilibili,看完了发现是用了上一题的reverse函数新学一个库函数reverse
class Solution {
public:
string reverseStr(string s, int k) {
for (int i = 0; i < s.size(); i += 2*k){
if (i + k <= s.size()) reverse(s.begin() + i, s.begin() + i + k);
else reverse(s.begin() + i, s.end());
}
return s;
}
};
下面是自己设计reverse函数的代码。
class Solution {
public:
void reverse(string& s, int start, int end){
int i = start;
int j = end;
for(;i < j; i++, j--){
swap(s[i], s[j]);
}
}
string reverseStr(string s, int k) {
for (int i = 0; i < s.size(); i += 2*k){
if(i + k <= s.size()) reverse(s, i, i + k - 1);
else reverse(s, i, s.size() - 1);
}
return s;
}
};
一道妙题。
第三题是替换数字https://kamacoder.com/problempage.php?pid=1064,对字符串大小扩容没把握好。看了卡哥的思路代码随想录,没想到竟然还用了双指针法。先扩容,从后往前填充。道高一尺,魔高一丈啊。
#include
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.resize(s.size() + count*5);
int snewsize = s.size();
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 <
学到了字符串如何填充替换,这道题的双指针运用确实隐晦。
第四题是翻转字符串里的单词https://leetcode.cn/problems/reverse-words-in-a-string/,又是一道中等题。没啥想法,找卡哥代码随想录。有迭代的思想,先翻转整体,在对各个单词进行翻转。
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;
for(int i = 0; i < s.size(); ++i){
if (s[i] != ' '){
if (slow != 0) {s[slow] = ' '; slow++;}
while(i < s.size() && s[i] != ' '){
s[slow++] = s[i++];
}
}
}
s.resize(slow);
}
string reverseWords(string s) {
removeExtraSpaces(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;
}
};
去除空格时巧妙利用了数组中双指针去除元素的逻辑。
第五题是右旋字符串https://kamacoder.com/problempage.php?pid=1065,召唤卡哥代码随想录。先把两部分倒叙输出,再分别对子串翻转。代码很简洁,很美。
#include
#include //妙啊
using namespace std;
int main(){
int n;
cin >> n;
string s;
cin >> s;
int len = s.size();
reverse(s.begin(), s.end());
reverse(s.begin(), s.begin() + n);
reverse(s.begin() + n, s.end());
std::cout << s << std::endl;
}
或者也可以先翻转子串,再翻转整体。
#include
#include
using namespace std;
int main(){
int n;
cin >> n;
string s;
cin >> s;
int len = s.size();
reverse(s.begin(), s.begin() + len - n);
reverse(s.begin() + len - n, s.end());
reverse(s.begin(), s.end());
std::cout << s << std::endl;
}
连做5道题,花了3个小时不得不说,代码跑出来的那一刻还是很开心的哈哈,最大的收获是对字符串的反转理解更深了,希望赶紧进入栈和队列。