美文网首页
3. 无重复字符的最长子串

3. 无重复字符的最长子串

作者: gykimo | 来源:发表于2021-08-09 10:30 被阅读0次

    题目:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/
    给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

    我的方法一:动态规划,O(N*N),O(N)

    步骤

    1. 子问题
      1.1 最后一步:最长子串或者包含最后一个字符,或者不包含
      1.2 子问题:去除最后一个字符的字符串的最长子串的长度,和以最后一个字符为结尾的最长子串的长度谁大
    2. 转移方程
      dp[n] = max(dp[n-1], 以最后一个字符为结尾的不重复字符的长度)
    3. 初始条件
      dp[0] = 1;
    4. 边界条件
      n<s.size()
    5. 计算顺序
      dp[0] dp[1] dp[N]
    6. 优化点,有dp[n]只和dp[n-1]有关,所以没必要保存所有的dp,只记录当前已知最大的即可。

    复杂度

    时间:两层循环,所以最大是O(N*N)
    空间:使用了哈希表,当所有字符都不相同时,最大是O(N)

    代码

    class Solution {
    public:
        int lengthOfLongestSubstring(string s) {
            if(s.size() == 0){
                return 0;
            }
    
            unordered_set<char> set;
            const char* p_s = s.c_str();
            int size = s.size();
            int max_long = 0;
            char tmp;
    
            //时间O(N),空间set最大是O(N)
            for(int i = 0; i < size; i++){
                set.clear();
    
                //时间最大是O(N)
                for(int j = i; j >= 0; j--){
                    tmp = p_s[j];
                    if(set.find(tmp) != set.end()){
                        break;
                    }
                    set.insert(tmp);
                }
    
                if(max_long < set.size()){
                    max_long = set.size();
                }
            }
    
            return max_long;
        }
    };
    

    我的方法二:双指针,O(N),最大O(N)

    和官方解法的滑动窗口类似,

    步骤

    1. 快慢指针,都从第0个字符开始遍历;使用一个哈希表set存储当前以快指针为结尾的不重复字符串;
    2. 先判断快指针对应的字符是否在set中,如果不在,说明该字符可以加到set中,这样长度就会变长;如果字符在set中,说明存在重复的字符,这个时候移动慢指针,并将慢指针对应的字符从set中去除,直到将快指针对应的字符从set移除为止;
    3. 期间set的最大长度就是最终的结果

    初始条件

    1. 快慢指针都指向第一个字符

    边界条件

    1. 快指针遍历完了整个字符串

    复杂度

    时间:O(N),快指针遍历了一遍,慢指针最大遍历了一遍,所以整体是O(N)
    空间:最大O(N),当所有字符都不想等时,set的长度就是字符串的长度,所以是O(N)。

    代码

    class Solution {
    public:
        int lengthOfLongestSubstring(string s) {
            if(s.size() == 0){
                return 0;
            }
    
            unordered_set<char> set;
            const char* p_s = s.c_str();
            int size = s.size();
            int max_long = 0;
            char tmp;
    
            int left = 0;
            int right = 0;
    
            //时间复杂度是O(N),因为right和left最大都从0遍历到N
            //空间复杂度最大是O(N)
            while(right < size) {
                if(set.find(p_s[right]) == set.end()){
                    set.insert(p_s[right]);
                    right++;
    
                    if(set.size() > max_long){
                        max_long = set.size();
                    }
                }else{
                    set.erase(p_s[left]);
                    left++;
                }
            }
    
            return max_long;
        }
    };
    

    相关文章

      网友评论

          本文标题:3. 无重复字符的最长子串

          本文链接:https://www.haomeiwen.com/subject/kknevltx.html