zoukankan      html  css  js  c++  java
  • 【LeetCode-字符串】无重复字符的最长子串

    题目描述

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

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

    题目链接: https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/

    思路1

    使用类似于求最大自序和的方法。设置两个指针left和right,left初始化为0,right初始化为1:

    • 判断当前字符s[right]是否在字符串s的[left,right)范围内出现过:
      • 如果没有出现,则将无重复子串长度加一,更新目前的无重复最长子串长度, right++;
      • 如果出现了,则将left更新为[left,right)范围内与当前字符s[right]相同且离得最远的字符下标,然后加1,求目前的子串长度,然后更新目前的无重复最长子串长度;
    • 重复上面的过程,直至rihgt>=s.length().
      代码如下:
    class Solution {
    public:
        int lengthOfLongestSubstring(string s) {
            if(s.empty() || s.length()==1){
                return s.length();
            }
    
            int left = 0;
            int right = left+1;
            int maxSubStrLen = 1;
            int curLen = 1;
            while(right<s.length()){
                int idx = find(s, left, right, s[right]);
                if(idx==-1){    // s[right]在[left,right)范围内没有出现
                    curLen++;
                    right++;
                    maxSubStrLen = max(curLen, maxSubStrLen);
                }else{ // s[right]在[left,right)范围内出现
                    left = idx+1;   // left此时是[left,right)范围内与s[right]相等且距离最远的下标+1
                    right++;
                    curLen = right-left;
                    maxSubStrLen = max(curLen, maxSubStrLen);
                }
            }
            return maxSubStrLen;
        }
        /*查找c是否在字符串s的[left,right)范围出现,如果出现则返回下标,否则返回-1*/
        int find(string s, int left, int right, char c){
            for(int i=left; i<right; i++){
                if(c==s[i]){
                    return i;
                }
            }
            return -1;
        }
    };
    
    • 时间复杂度: O(n^2)
      首先遍历一遍元素,在遍历每个元素的过程中还要查看该元素是否在前面出现过。
    • 空间复杂度:O(1)

    思路2

    维持一个队列,该队列中不包含重复的元素,且该队列中的元素是连续的(滑动窗口)。例如字符串"abcabcbb",假设当前队列中的元素为前3个字符"abc",下一个元素为"a",在队列中出现过,则将队列最左边的元素移除,直至队列中不包含下一个元素"a",记录当前的长度和当前的最大长度。代码如下:

    class Solution {
    public:
        int lengthOfLongestSubstring(string s) {
            if(s.empty() || s.length()==1){
                return s.length();
            }
    
            unordered_set<char> lookup;
            int left = 0;
            int right = 0;
            int maxSubStrLen =1;
            while(right<s.length()){
                if(lookup.find(s[right])!=lookup.end()){    // 当前元素s[right]在窗口中出现
                    lookup.erase(s[left]);
                    left++;
                }else{  // 当前元素s[right]没有在窗口中出现
                    int curLen = right-left+1;
                    maxSubStrLen = max(curLen, maxSubStrLen);
                    lookup.insert(s[right]);
                    right++;
                }
            }
            return maxSubStrLen;
        }
    };
    
    • 时间复杂度: O(n)
    • 空间复杂度: O(1)
      虽然使用了set,但由于字符个数有限(256个),所以辅助空间的规模不会随输入规模的增大而增大,所以空间复杂度为O(1)。

    参考

    1、https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/solution/hua-dong-chuang-kou-by-powcai/

  • 相关阅读:
    hdu6393 Traffic Network in Numazu 树链剖分
    codeforces 1180E Serge and Dining Room 线段树
    codeforces 546E Soldier and Traveling 网络流
    E
    poj3207 Ikki's Story IV
    【2020牛客多校第二场】F Fake Maxpooling
    【2020牛客多校第一场】J Easy Integration
    【ICPC2015沈阳M】Meeting
    【 AtCoder Beginner Contest 169】C Multiplication 3
    【AtCoder Beginner Contest 169】B Multiplication 2
  • 原文地址:https://www.cnblogs.com/flix/p/12679874.html
Copyright © 2011-2022 走看看