剑指offer 之 string
1 翻转字符串
剑指offer 58-1:翻转单词顺序如输入字符串"I am a student. “,则输出"student. a am I”。
思路1:后序遍历+i/j单词起止位置+string容器的尾插法(s.push_back())
#include <memory>
#include <iostream>
using namespace std;
class Solution {
public:
string reverseWords(string s) {
string str;//str为逆序单词字符串
if(s.empty()) //输入字符为空,返回空
return str;
int i,j;
for(j= s.size() - 1; j >= 0; --j)
{
if(s[j] != ' ') //遇到不是空格的
{
i = j;
while(i >=0 && s[i] != ' ') //从j开始向左寻找单词,i>=0防止越界访问
--i;
for(int k = i + 1; k <= j; ++k) //单词序列加入字符串中
str.push_back(s[k]);//尾插法
str.push_back(' '); //加入一个空格
j = i; //改变j的位置
}
}
if(str.size() > 0)
str.pop_back(); //移除末尾空格
return str;
}
};
int main() {
Solution S;
string s ="A handsome boy";
string show = S.reverseWords(s);
cout << "原单词顺序:"<< s <<endl;
cout << "翻转后顺序:"<< show<< endl;
system("pause");
return 0;
}
//时间:4ms 96.28%
//内存消耗:7.7MB 82.69%
思路2:栈+istringstream
#include <memory>
#include <iostream>
using namespace std;
class Solution {
public:
string reverseWords(string s) {
stack<string> stk;
string temp,res;
//读取s中的字符串,传给temp
istringstream is(s);
//将temp中字符串入栈
while (is >> temp) {
stk.push(temp);
stk.push(" ");
}
if(stk.size()>0) stk.pop();
//栈:先进后出 把栈中的单词传给res
while (stk.size()>0) {
res += stk.top();
stk.pop(); //传完一个单词就释放掉stk栈顶元素
}
return res;
}
};
//时间:4ms 96.28%
//内存消耗:8.7MB 44.86%
2 左旋转字符串
剑指offer 58-2:把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。
思路1:截取子串(时间O(1),空间大))
class Solution {
public:
string reverseLeftWords(string s, int n) {
if(s.empty()){
return s;
}
//s.substr(star_pos, end_pos) 从star_pos开始,截取end_pos -star_pos个字符
return s.substr(n, s.length() - 1) + s.substr(0,n);
}
};
//时间:0ms 100%
//内存消耗:8.2MB 10%
思路2:用reverse翻转(时间O(n),空间小)
class Solution {
public:
string reverseLeftWords(string s, int n) {
if(s.empty()){
return s;
}
reverse(s.begin(), s.begin() + n);
reverse(s.begin() + n, s.end());
reverse(s.begin(), s.end());
return s;
}
};
//时间:4ms 89.63%
//内存消耗:7.3MB 81.12%