剑指offer Leetcode 48. 最长不含重复字符的子字符串

image-20201215164310669

解法1:滑动窗口

思想:

​ 用set维护一个不重复的滑动窗口,得到以s[right]为结尾的最长无重复子串(即s[left]到s[right])。

复杂度:

​ ●时间:O(N),for循环需遍历n次,while循环只有重复才执行,就算最坏情况下全部重复也就执行N次,所以O(N) + O(N)

​ ●空间:O(1),set中最多存储128个数。使用vector效率更高。

代码:

class Solution {
    
    
public:
    int lengthOfLongestSubstring(string s) {
    
    
        int res = 0;
        unordered_set<char>my_set;
        for(int left = 0, right = 0; right < s.size(); right++){
    
    
            //如果s[right]重复了,就从left开始弹出(left++),直到不重复
            while(my_set.find(s[right]) != my_set.end())
                my_set.erase(s[left++]);
            //插入当前s[right]字符
            my_set.insert(s[right]);
            //因为当前只是以s[right]结尾的最长子串,所以每轮需要更新一下
            res = max(res, right - left + 1);
            //res = max(res, int(my_set.size())); 用set.size()更好理解一点,因为里面都是不重复的
        }
        return res;
    }
};

改进:

​ 思想:关于字符的set都可以用vector来代替,这样可以提高效率。

​ 注意:可以用vec_exist[s[right]]来直接访问数组,即ASCII码为index直接访问

class Solution {
    
    
public:
    int lengthOfLongestSubstring(string s) {
    
    
        if(s.size() <= 1)
            return s.size();
        int res = 0;
        //注意题目说的是字符,不是字母,所以要128个
        vector<int>vec_exist(128, 0);
        for(int left = 0, right = 0; right < s.size(); right++){
    
    
            while(vec_exist[s[right]] > 0)
                vec_exist[s[left++]] = 0;
            vec_exist[s[right]] = 1;
            res = max(res, right - left + 1);
        }
        return res;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_36459662/article/details/113955455
今日推荐