day8
344.反转字符串
可以left<right
更直接
class Solution {
public:
void reverseString(vector<char>& s) {
int len = s.size();
char tmp;
for (int i = 0; i < len / 2; i++) {
tmp = s[i];
s[i] = s[len - 1 - i];
s[len - 1 - i] = tmp;
}
return ;
}
};
541. 反转字符串II
c++参数传递,没加&是拷贝过来一份,所以要返回string作为结果。
class Solution {
public:
void reverse(string& s, int cur, int k) {
for (int i = cur, j = cur + k - 1; i < j; i++, j--)
swap(s[i], s[j]);
}
string reverseStr(string s, int k) {
int len = s.size();
int cur = 0;
for (cur = 0; cur + 2*k <= len; cur += 2*k) {
reverse(s, cur, k);
}
if (cur + k > len) reverse(s, cur, len - cur);
else reverse(s, cur, k);
return s;
}
};
剑指05.替换空格
因为是string,空格替换成 “%20” 要多两个char,第一思路是用另一个string来返回,这样可能时间上比较快?缺点是用了额外的辅助空间。
Karl的思路也很有意思,又是一次双指针的美妙使用,既然string每次加东西,后面的元素都要后移,那直接第一遍遍历算好一共要移多少空间,然后再用双指针从后往前拉回来。
建议:对于线性数据结构(非链表),填充或者删除,后序处理会高效的多。——Karl
class Solution {
public:
string replaceSpace(string s) {
int num = 0;
for (char c: s)
if (c == ' ') num++;
int i = s.size() - 1;
s.resize(s.size() + num*2);
int j = s.size() - 1;
// cout << i <<" "<< j;
for (; i >= 0; i--,j--) {
if (s[i] == ' ') {
s[j] = '0'; s[j-1] = '2'; s[j-2] = '%';
j -= 2;
}
else s[j] = s[i];
}
return s;
}
};
用栈写的屎山:
class Solution {
public:
string reverseWords(string s) {
stack<string> st;
int len = s.size();
int i = 0;
while (i < len) {
while (i < len && s[i] == ' ') i++;
string tmp;
while (i < len && s[i] != ' ') {
tmp.push_back(s[i]);
i++;
}
if (tmp.size() > 0) st.push(tmp);
}
string res;
res = res + st.top();
st.pop();
while (!st.empty()) {
res.append(" ");
res.append(st.top());
st.pop();
}
return res;
}
};
151.翻转字符串里的单词
这题好麻烦,理不清就显得好难。
确实很综合。
class Solution {
public:
string reverseWords(string s) {
reverse(s.begin(),s.end());
//删除多余空格
int slow = 0, fast = 0;
// 越过开头的空格
while (s[fast] == ' ') fast++;
//找中间的空格
while (fast < s.size()) {
if (s[fast] != ' ') {
s[slow++] = s[fast++];
}
else {
s[slow++] = ' ';
while (fast < s.size() && s[fast] == ' ') fast++;
}
}
// 剔除最后的空格
int last = slow - 1;
while (s[last] == ' ') last--;
s.resize(last + 1);
// 对逐个单词的反转
for (slow =0, fast =0; fast <= s.size(); fast++){
if (fast >= s.size() || s[fast] == ' '){
reverse(s.begin() + slow, s.begin() + fast);
slow = fast + 1;
}
}
return s;
}
};
另外对 reverse()
函数(#include <algorithm>
)也熟悉了一下,有两种用法:
反转数组:reverse(a, a+n); //n为数组中的元素个数
,
反转字符串 :reverse(str.begin(), str.end());
反转向量:reverse(vec.begin(), vec.end());
剑指58-II.左旋转字符串
首先,基本的string操作得会用。
string reverseLeftWords(string s, int n) {
string tmp1 = s.substr(0, n), tmp2 = s.substr(n);
return tmp2.append(tmp1);
}
确实妙啊!局部反转在整体反转,和前面的题目融会贯通了。
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;
}
};