1.LeetCode38. 外观数列
题目读懂就好做了
class Solution {
public:
string countAndSay(int n) {
string s("1"), t;
for(int i = 1; i < n; i ++){
t = "";
for(int j = 0; j < s.size(); j ++){
int k = 0;
while(s[j] == s[j + k]) k ++;
t += to_string(k) + s[j];
j += k - 1;
}
s = t;
}
return s;
}
};
2.LeetCode49. 字母异位词分组
对字母异位词排序后的结果相同。将结果相同的字符串放到同一个vector里(通过映射)。
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
unordered_map<string, vector<string>> mp;
vector<vector<string>> ans;
for(auto& s: strs){
string ss = s;
sort(ss.begin(), ss.end());
mp[ss].push_back(s);
}
for(auto &item: mp)
ans.push_back(item.second);
return ans;
}
};
3.LeetCode151. 翻转字符串里的单词
字符流来做
class Solution {
public:
string reverseWords(string s) {
stringstream ss(s);
string ans, tmp;
while(ss >> tmp){
ans = " " + tmp + ans;
}
ans.erase(0,1);
return ans;
}
};
二次反转,原地解法,空间O(1)。字符串问题一定要把边界情况考虑清楚,遍历时最好都加上是否越界的判断。
class Solution {
public:
string reverseWords(string s) {
int k = 0;//k进行反转后单词的更新
for(int i = 0; i < s.size(); i ++){
while(i < s.size() && s[i] == ' ') i ++;
if(i >= s.size()) break;
int j = i;
while(j < s.size() && s[j] != ' ') j ++;
reverse(s.begin() + i, s.begin() + j);
//第一个单词前不加空格
if(k) s[k ++] = ' ';
while(i < j) s[k ++] = s[i ++];
}
s.erase(s.begin()+k, s.end());
reverse(s.begin(), s.end());
return s;
}
};
4.LeetCode165. 比较版本号
class Solution {
public:
int compareVersion(string s1, string s2) {
for(int i = 0, j = 0; i < s1.size() || j < s2.size(); i ++, j ++){
int a = 0, b = 0, ii = i, jj = j;
while(ii < s1.size() && s1[ii] != '.') ii ++;
while(jj < s2.size() && s2[jj] != '.') jj ++;
if(ii > i) a = stoi(s1.substr(i, ii-i));
if(jj > j) b = stoi(s2.substr(j, jj-j));
if(a > b) return 1;
else if(a == b) i = ii, j = jj;
else return -1;
}
return 0;
}
};
5.LeetCode929. 独特的电子邮件地址
class Solution {
public:
int numUniqueEmails(vector<string>& emails) {
unordered_set<string> st;
for(auto &s : emails){
string ss;
for(int i = 0; i < s.size(); i ++){
if(s[i] == '.') continue;
else if(s[i] == '+'){
while(s[i] != '@') i ++;
i --;
}
else if(s[i] == '@') {
ss += s.substr(i, s.size());
break;
}
else ss += s[i];
}
st.insert(ss);
}
return st.size();
}
};
6.LeetCode5. 最长回文子串
中心扩散
class Solution {
public:
string longestPalindrome(string s) {
string ans;
for(int i = 0; i < s.size(); i ++){
//奇数情况
for(int j = i, k = i; j >= 0 && k < s.size(); j -- , k ++){
if(s[j] == s[k]) {
if(k - j + 1 > ans.size()) ans = s.substr(j, k-j+1);
}
else break;
}
//偶数情况
for(int j = i, k = i+1; j >= 0 && k < s.size(); j -- , k ++){
if(s[j] == s[k]) {
if(k - j + 1 > ans.size()) ans = s.substr(j, k-j+1);
}
else break;
}
}
return ans;
}
};
7.LeetCode6. Z 字形变换
class Solution {
public:
string convert(string s, int n) {
if(n == 1) return s;
string ans;
int len = s.size(), dif = 2 * (n -1);
//找规律,枚举每行
for(int i = 0; i < n; i ++){
//第0行和第n-1行元素的下标是等差数列,初始下标为0(n-1),公差为2*(n-1)
if(i == 0 || i == n-1){
for(int j = i; j < len; j += dif){
ans += s[j];
}
}
//其余行可看成两个等差数列
//初始下标为i,公差为2*(n-1)。初始下标为2*(n-1)-i,公差为2*(n-1)。
else{
for(int j = i, k = dif-i; j < len || k < len; j += dif, k += dif){
if(j < len) ans += s[j];
if(k < len) ans += s[k];
}
}
}
return ans;
}
};
8.LeetCode3. 无重复字符的最长子串
比较经典的双指针算法问题了
class Solution {
public:
int lengthOfLongestSubstring(string s) {
unordered_map<char, int> mp;
int ans = 0;
for(int i = 0, j = 0; j < s.size(); j ++){
mp[s[j]] ++;
while(mp[s[j]] > 1) mp[s[i++]] --;
ans = max(ans, j - i + 1);
}
return ans;
}
};