字符串问题总结

1.无重复字符的最长字串

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

输入: "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:

输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:

输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

这题的最优解法是滑动窗口,一开始我是一直保持窗口只会增大不会增小,具体做法是一次遍历,每次检查数组是否存在大于一的,代表有重复的字符串,滑动窗口平移,当不存在重复字符串时,滑动窗口向右增大,这种做法开销在于检查数组,所以还挺耗时的。
优化的做法为一次遍历,将i一直作为滑动窗口的右窗口,最大值为遍历的最大的窗口大小,每次遍历时,左窗口为max(l,v[s[i]]),当窗口中没有重复的数字时,v[s[i]]是0或者一个比l小的值,当有重复的数字时,跳到窗口内第一个不存在重复字符的地方,改变右窗口的字符所在的数组的值,该值为右窗口+1,左窗口根据这个值移动。

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if(s.empty())return 0;
        vector<int> v(128, 0);
        int l = 0;
        v[s[0]] = 1;
        int ret = 1;
        for(int i = 1; i < s.size(); i++){
            l = max(l, v[s[i]]);
            ret = max(ret, i-l+1);
            v[s[i]] = i+1;
        }
        return ret;
    }
};

2.字符串出现的最大次数

给你一个字符串 s ,请你返回满足以下条件且出现次数最大的 任意 子串的出现次数:

子串中不同字母的数目必须小于等于 maxLetters 。
子串的长度必须大于等于 minSize 且小于等于 maxSize 。
 

示例 1:

输入:s = "aababcaab", maxLetters = 2, minSize = 3, maxSize = 4
输出:2
解释:子串 "aab" 在原字符串中出现了 2 次。
它满足所有的要求:2 个不同的字母,长度为 3 (在 minSize 和 maxSize 范围内)。
示例 2:

输入:s = "aaaa", maxLetters = 1, minSize = 3, maxSize = 3
输出:2
解释:子串 "aaa" 在原字符串中出现了 2 次,且它们有重叠部分。
示例 3:

输入:s = "aabcabcab", maxLetters = 2, minSize = 2, maxSize = 3
输出:3
示例 4:

输入:s = "abcde", maxLetters = 2, minSize = 3, maxSize = 3
输出:0
 

提示:

1 <= s.length <= 10^5
1 <= maxLetters <= 26
1 <= minSize <= maxSize <= min(26, s.length)
s 只包含小写英文字母。

这道题的基本方法是用滑动窗口,我们可以分析出窗口的大小只与minSize有关,而与maxSize无关,滑动窗口固定后就方便解决了。我在解这道题的时候出现了错误,一开始我使用了string的find函数来统计每个字串的个数,可这样做效率太低,时间复杂度非常大,然后我用一个备忘录来记录是否有相同的字串已经被记录过,结果发现依然超时。。。其实只需要以空间换时间的方法,用哈希表保存每个字串,value为字串的个数即可。。。
总结:字符串问题大部分遍历可以用哈希表来优化时间,如two sum问题,一定不要死脑筋。

class Solution {
public:
    int maxFreq(string s, int maxLetters, int minSize, int maxSize) {
        unordered_map<char, int> m;
        unordered_map<string, int> h;
        int l = 0;
        int max_ = 0;
        for(int r = 0; r < s.size(); r++){
            m[s[r]]++;
            if(r-l+1 < minSize){
                continue;
            }
            if(m.size() > maxLetters){
                m[s[l]]--;
                if(m[s[l]] == 0)
                    m.erase(s[l]);
                l++;
                continue;
            }
            string temp = s.substr(l, r-l+1);
            h[temp]++;
            m[s[l]]--;
            if(m[s[l]] == 0)
                m.erase(s[l]);      
            l++;      
        }
        for(auto &n:h){
            max_ = max(max_, n.second);
        }
        return max_;
    }
};
发布了18 篇原创文章 · 获赞 0 · 访问量 285

猜你喜欢

转载自blog.csdn.net/weixin_42162340/article/details/103635122