字符串处理习题(1)

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;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值