题目1:假设现在有一个初始字符串为1,那么下一个字符串就是按连续相同数字的个数读出上一个字符串。
例子:
1
11
21
1211
111321
1读作one 1,所以下一个字符串是11
11读作two 1s,所以下一个字符串是21
21读作one 2,then one 1,所以下一个字符串是1211
给出n,返回第n个字符串。
input:1
output:“1”
input:4
output:“1211”
简单的说,就是字符串中,以1开头的字符进行拆分,即“1211”可以拆分为“12”和“11”两个字符串,并读作“1”个“2”,以及“1”个“1”.
class solution{
public:
string countAndSay(int n){
string s = "1";
for(int i = 1; i < n; i++){
string ns = "";
for(int j = 0;j<s.size();){
int u = j;
while(u < s.size() && s[u] == s[j]) u++;
ns += to_string(u - j);
ns += s[j];
j = u;
}
s = ns;
}
return s;
}
};
题目2:给定一组字符串,将所有字母顺序颠倒的字符串归为一组。
注意:
- 所有输入均是小写字母
- 输出顺序随意
样例:
输入:
{"eat","tea","tan","ate","nat","bat"}
输出:
{
{"ate","eat","tea"},
{"nat","tan"},
{"bat"}
}
思路:采用哈希表的方式 O(NLlogL)
定义从string映射到vector<string>的哈希表:unordered_map<string,vector<string>>,我们将每个字符串的所有字符从小到大进行排序,将排好序的字符串作为key,然后将原字符串插入vector<string>中。
class solution{
public:
vector<vector<string>> groupAnagrams(vector<string> &strs){
unordered_map<string,vector<string>> hash;
for(auto s : strs){
string rs = s;
sort(s.begin(),s.end());
hash[s].push_back(rs);
}
vector<vector<string>> res;
for(auto &group : hash){
res.push_back(group.second);
}
return res;
}
};
题目3:给定一个字符串,请将字符串中单词的顺序倒过来。
注意:
- 单词是指连续非空格字符
- 单词之间可能包含多余空格,请在结果中删除多余空格,使得单词之间仅包含一个空格
- 请删除字符串首尾多余的空格
进一步:能否只使用额外O(1)的空间?
样例:
输入:"the sky is blue",
输出:"blue is sky the".
思路:数组翻转O(n)
- 将字符串中的每个单词逆序,样例输入变为:"eht yks si eulb";
- 将整个字符串逆序,样例输入变为:"blue is sky the";
class solution{
public:
void reverseWords(string &s){
int i = 0, k = 0;
s += ' ';
while(k < s.size() && s[k] == ' ') k++;
while(k < s.size()){
if(s[k] != ' ')
s[i++] = s[k++];
else{
s[i++] = ' ';
while(k < s.size() && s[k] == ' ') k++;
}
}
if(!i){
s = "";
return;
}
s.erase(s.begin() + i - 1, s.end());
for(int i = 0; i < s.size(); i++){
int j = 1;
while(j < s.size() && s[j] != ' ') j++;
reverse(s.begin() + 1,s.begin() + j);
i = j;
}
reverse(s.begin(),s.end());
}
}