leetcode-pp / 91alg-6-daily-check

91 算法第六期打卡仓库
28 stars 0 forks source link

【Day 22 】2022-01-02 - 3. 无重复字符的最长子串 #29

Open azl397985856 opened 2 years ago

azl397985856 commented 2 years ago

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

入选理由

暂无

题目地址

https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/

前置知识

示例 1:

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

示例 2:

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

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

yan0327 commented 2 years ago

思路: 哈希表 + 双指针(滑动窗口) 思路用一个左指针指窗口的最左端,遍历右端 一旦发现哈希表中曾经出现过当前遍历的值,则for循环收缩窗口,直到当前值的哈希映射为0 则继续右移扩展窗口。 每次需要判断是否超过最长字符串,若超过则更新。

func lengthOfLongestSubstring(s string) int {
    hash := map[byte]int{}
    l := 0
    out := 0
    for r := range s{
        for hash[s[r]] > 0{
            hash[s[l]]--
            l++
        }
        hash[s[r]]++
        if r-l+1 > out{
            out = r-l+1
        }
    }      
    return out
}

时间复杂度O(N) 空间复杂度O(N)

sonicliyang commented 2 years ago

同向双指针滑窗+charArray记录出现次数: class Solution { public int lengthOfLongestSubstring(String s) { int start = 0; int end = 0; int result = 0; int[] charList = new int[128]; Arrays.fill(charList, -1); while (end < s.length()) { char letter = s.charAt(end); if (charList[letter] != -1 && charList[letter] >= start && charList[letter] < end) { start = charList[letter] + 1; } result = Math.max(result, end - start + 1); charList[letter] = end; end++; } return result; } }

ninghuang456 commented 2 years ago
class Solution {
    public int lengthOfLongestSubstring(String s) {
       if (s == null || s.length() == 0) return 0;
       HashMap<Character, Integer> window = new HashMap<>(); 
       int left = 0; int right = 0; int maxLen = 0;
       while(right < s.length()){
           char s1 = s.charAt(right);
           right ++;
           window.put(s1, window.getOrDefault(s1, 0) + 1);
           while (window.get(s1) > 1){
               char s2 = s.charAt(left);
               left ++;
               window.put(s2, window.getOrDefault(s2,0) - 1);
           }
          maxLen = Math.max(maxLen, right - left); 
       } 

       return maxLen;   
    }
}
//Time O(n), Space O(n)
Davont commented 2 years ago

思路

滑动窗口

code

var lengthOfLongestSubstring = function(s) {
    const hash = new Set()
    let res = 0, right = -1 //右指针从左指针左边开始
    for(let left = 0; left < s.length; left++){
        if(left != 0){
            hash.delete(s.charAt(left-1))
        }
        while(right+1 < s.length && !hash.has(s.charAt(right+1))){
            hash.add(s.charAt(right+1))
            right++
        }
        res = Math.max(res, right - left + 1)
    }
    return res
};
wxj783428795 commented 2 years ago

思路

  1. 遍历字符串,记录无重复字串的左侧下标。
  2. 当前字符在目前子串中时,将左侧下标更新。
  3. 当前字符不在目前子串中时,更新最大长度。

代码

/**
 * @param {string} s
 * @return {number}
 */
var lengthOfLongestSubstring = function (s) {
    if (!s.length) return 0;
    let max = 0;
    let left = 0;
    let str = ''
    for (let i = 0; i < s.length; i++) {
        if (str.includes(s[i])) {
            left += s.slice(left, i).indexOf(s[i]) + 1
            continue;
        }
        str = s.slice(left, i + 1);
        max = Math.max(max, str.length);
    }
    return max;
};

复杂度分析

复杂度分析不是很会,不一定对,如果有错,请指正。

wenjialu commented 2 years ago

thought

Sliding win

code

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        # win:set. new char is not in it, append win; else, shink win until no dupli.
        # why could not use set?? 
        # hash
        win = {}
        left, right = 0, 0
        longest = 0
        for right in range(len(s)):
            if s[right] in win:
                # print(win, s[right], left, right) 
                left =  max(left, win[s[right]] + 1) 

            win[ s[right] ] =  right  
            longest = max(longest, right - left + 1) 
        return longest

com

Time:O(n) Space:O(n)?

chakochako commented 2 years ago
class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        ans = 0
        left, right = 0, 0
        seen = {}

        while right < len(s):
            cur = s[right]                                                                                    
            right = right + 1
            seen[cur] = seen.get(cur,0) + 1
            #print(seen)

            while seen.get(cur) > 1:
                seen[s[left]] = seen[s[left]] - 1
                left = left + 1
                #print(left, right)

            ans = max(ans, right - left)
BpointA commented 2 years ago

思路

滑动窗口

Java代码

class Solution {
    public int lengthOfLongestSubstring(String s) {
        HashMap<Integer,Integer>d= new HashMap<>();
        int left=0;
        int right=0;
        int m=s.length();
        int ans=0;
        while (right<m)
        {
            int x=s.charAt(right)-'a';
            while(d.getOrDefault(x,0)>0 && left<right)
            {
                int y=s.charAt(left)-'a';
                d.put(y,d.getOrDefault(y,0)-1);
                left+=1;

            }
            d.put(x,d.getOrDefault(x,0)+1);
            right+=1;
            if (right-left>ans)
            {
                ans=right-left;
            }
        }
        return ans;
    }
}
charlestang commented 2 years ago

思路

双指针。用两个指针夹住一段子串。用一个集合记录见到过的字符。

如果右指针指向的字符,集合里没有,就向右扩展区间。并且计算最大长度。

如果右指针指向的字符,集合里已经有了,就收缩左指针,并移除左指针指向的字符,直到右指针指向的字符在集合中已经没有重复。

代码

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        n = len(s)
        if not n: return 0
        seen = set()
        left, right, ans = 0, 0, 0
        while right < n:
            if s[right] not in seen:
                seen.add(s[right])
                right += 1
                ans = max(ans, right - left)
            else:
                while s[right] in seen:
                    seen.remove(s[left])
                    left += 1
        return ans

时间复杂度 O(n)

空间复杂度 O(n)

tian-pengfei commented 2 years ago
class Solution {
public:
    int lengthOfLongestSubstring(string s) {

        if(s.empty())return 0;
        if(s.length()==1)return 1;
        int max_length  = 1,current_length=1;
        int start_pos = 0;
        int end_pos = 1;
        while(end_pos!=s.length()){
            const char c=s[end_pos];
            int pos = s.find(c,start_pos);
            if(pos==string::npos||start_pos>pos||pos==end_pos){
                end_pos++;
                current_length++;
                max_length=max(max_length,current_length);
            }else{
                current_length = end_pos-pos;
                start_pos =pos+1;
                end_pos++;
            }
        }

        return max_length;

    }
};
zhiyuanpeng commented 2 years ago
from collections import defaultdict
class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        # sliding wid
        l = 0
        pool = defaultdict(int)
        # 
        ans = 0
        for r in range(len(s)):
            if s[r] in pool:
                # find duplicate
                # move the l to make sure pool[s[r]] == 0
                while pool[s[r]] != 0:
                    # -1 then move l 
                    pool[s[l]] -= 1
                    # if == 0, remove the key
                    if pool[s[l]] == 0:
                        del pool[s[l]]
                    l += 1
            # after remove the dupliate
            pool[s[r]] += 1
            ans = max(ans, r-l+1)
        return ans

time O(N) space O(N)

laofuWF commented 2 years ago
class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        if (not s or len(s) == 0): return 0

        # stores last seen index of a character
        seen = {}
        res = left = 0

        for right, char in enumerate(s):
            if char in seen and left <= seen[char]:
                left = seen[char] + 1
            else:
                res = max(res, right - left + 1)
            seen[char] = right

        return res
YuhanJYH commented 2 years ago

思路: sliding window + hash map

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        //sliding window algorithm
        int size = s.length();

        if(size < 2)
        {
            return size;
        }

        int left{0}, right{0}, ans{1}; //indicator
        unordered_map<char, int> memo;
        for(auto c: s) //initialize memo
        {
            memo[c] = 0;
        }

        for(;right < size; right++)
        {
            char cur = s[right];
            memo[cur]++;

            for(; memo[cur] > 1; left++)
            {
                memo[s[left]]--;
            }

            ans = max(ans, right-left+1);
        }
        return ans;
    }
};

time: o(n) space : o(n)

Bochengwan commented 2 years ago

思路

双指针+hashmap,通过hashmap来计算字符的frequency。

代码

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        if not s:
            return 0

        m = defaultdict(int)
        ans = 0
        start = 0
        for i,e in enumerate(s):
            m[e]+=1

            if m[e]>1:
                ans = max(ans,i-start)
                while start<i:
                    cur = s[start]
                    m[cur]-=1
                    start+=1
                    if cur == e:
                        break
            else:
                ans = max(ans, i-start+1)
        return ans

复杂度分析

feifan-bai commented 2 years ago

思路

  1. 滑动窗口,将字符串进入队列,通过指针从左到右滑动字符串查找
  2. 如果不满足要求,移动左边元素,直至符合题意
  3. 用cur_len记录当前长度,max_len存储最大长度,返回max_len 代码
    class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        seen = []
        max_len, cur_len = 0, 0
        left = 0
        for i in range(len(s)):
            cur_len += 1
            while s[i] in seen:
                seen.remove(s[left])
                left += 1
                cur_len -= 1
            max_len = max(max_len, cur_len)
            seen.append(s[i])
        return max_len

    复杂度分析

    • 时间复杂度:O(N)
    • 空间复杂度:O(N)
zjsuper commented 2 years ago

class Solution: def lengthOfLongestSubstring(self, s: str) -> int:

dic position value length

    dic = defaultdict(int)
    ans = 0
    for i in range(len(s)):
        c = 0
        lis = []
        for j in range(i,len(s)):

            if s[j] not in lis:
                lis.append(s[j])
                c+=1
                #print(lis)
            else:
                break

        ans = max(ans,c)
        #print(ans)
    return ans
zwmanman commented 2 years ago

class Solution(object): def lengthOfLongestSubstring(self, s): """ :type s: str :rtype: int """ res = 0 helper = collections.defaultdict(int)

    if not s:
        return 0

    l = 0
    r = 0

    while r <= len(s) - 1:
        if helper[s[r]] == 0:
            res = max(res, r - l + 1)
            helper[s[r]] += 1
            r += 1
        else:
            helper[s[l]] -= 1
            l += 1

    return res
Liuxy94 commented 2 years ago

思路

滑动窗口

代码

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        if not s:return 0
        left = 0
        lookup = set()
        n = len(s)
        max_len = 0
        cur_len = 0
        for i in range(n):
            cur_len += 1
            while s[i] in lookup:
                lookup.remove(s[left])
                left += 1
                cur_len -= 1
            if cur_len > max_len:max_len = cur_len
            lookup.add(s[i])
        return max_len

复杂度分析

时间复杂度: O(n)

空间复杂度: O(s)

zhy3213 commented 2 years ago

思路

最高端的滑动窗口往往是看不到快慢指针的

代码

    def lengthOfLongestSubstring(self, s: str) -> int:
        if (l:=len(s))<=1:
            return l
        pos={}
        cur=0
        res=0
        for index,i in enumerate(s):
            if i in pos:
                for j in range(index-cur,last:=pos[i]):
                    del pos[s[j]]
                cur=index-last
                pos[i]=index
            else:
                pos[i]=index
                cur+=1
                if cur>res:
                    res=cur
        return res
CoreJa commented 2 years ago

思路

class Solution:
    # 哈希:naive想法,每次遇到重复的字符,从重复字符的起点开始重置字典重新统计,
    # 这样worst case复杂度就是O(n^2)
    def lengthOfLongestSubstring1(self, s: str) -> int:
        d = defaultdict(lambda: [0, -1])
        i, n = 0, len(s)
        ans = 0
        while i < n:
            ch = s[i]
            if d[ch][0] >= 1:
                ans = max(ans, len(d.keys()))
                i = d[ch][1] + 1
                d = defaultdict(lambda: [0, -1])
                continue
            d[ch][0] += 1
            d[ch][1] = i
            i += 1
        if len(d.keys()):
            ans = max(ans, len(d.keys()))
        return ans

    # 哈希+滑动窗口:上面方法的改进,不需要重置字典,因为除了那个重复的字符以外其它的字符都是没重复的,
    # 所以可以应用滑动窗口,当右指针扫到和set重复的情况,左指针向右滑直到找到这个重复的字符,
    # 滑动的同时从set中删掉。复杂度O(n)
    def lengthOfLongestSubstring(self, s: str) -> int:
        chars = set()
        ans = 0
        i = 0
        for ch in s:
            if ch not in chars:
                chars.add(ch)
            else:
                if len(chars) > ans:
                    ans = len(chars)
                while s[i] != ch:
                    chars.remove(s[i])
                    i += 1
                i += 1
        return ans if ans > len(chars) else len(chars)
cszys888 commented 2 years ago
class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        hashmap = {}
        max_len = 0
        start = 0 
        for idx in range(len(s)):
            letter = s[idx]
            if letter not in hashmap or hashmap[letter] < start:
                hashmap[letter] = idx
                max_len = max(max_len, idx + 1 - start)
            else:
                start = hashmap[letter] + 1
                hashmap[letter] = idx
        return max_len

time complexity: O(N) space complexity : O(K), K stands for the number of ASCII characters

xj-yan commented 2 years ago
class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        charMap = dict()
        i, maxLen = 0, 0
        for j in range(len(s)):
            c = s[j]
            if c in charMap.keys():
                i = max(i, charMap[c] + 1)
            charMap[c] = j
            maxLen = max(maxLen, j - i + 1)
        return maxLen

Time Complexity: O(n), Space Complexity: O(n)

yijing-wu commented 2 years ago

思路

滑动窗口

代码


class Solution {
    public int lengthOfLongestSubstring(String s) {
        int n = s.length(), res = 0;
        Map<Character, Integer> map = new HashMap<Character, Integer>();
        for (int start = 0, end = 0; end < n; end++){
            char ch = s.charAt(end);
            if(map.containsKey(ch)) {
                start = Math.max(map.get(ch),start);    // 进行滑动,start缩到该ch上一次出现的下一个位置
            }
            res = Math.max(res, end - start + 1);
            map.put(s.charAt(end), end + 1);
        }
        return res;
   }
}

复杂度分析

zhangzz2015 commented 2 years ago

思路

关键点

代码

C++ Code:

class Solution {
public:
    int lengthOfLongestSubstring(string s) {

        vector<int> record(256,0); 

        int left =0; 
        int right =0; 
        int ret =0; 
        while(right < s.size())
        {

            record[s[right]]++; 
            while(record[s[right]]>1)
            {
                record[s[left]]--; 
                left++; 
            }

            ret = max(ret, right - left +1); 

            right++; 

        }

        return ret; 
    }
};

class Solution {
public:
    int lengthOfLongestSubstring(string s) {

        vector<int> record(256,-1); 
        int left =0; 
        int ret =0;
        for(int i=0; i< s.size(); i++)
        {
            if(record[s[i]]!=-1)
            {
                ret = max(ret, i - left);
                left = max(left, record[s[i]]+1);                 
            }
            record[s[i]] = i; 
        }

        ret = max(ret, int(s.size()) - left); 

        return ret; 

    }
};
MengyuZang commented 2 years ago

Solution

  1. Could use brute force, n characters, so O(n^2) substring in total. Each substring takes O(n) to check with a HashTable/array, so O(n^3)

  2. Try HashMap and Sliding Window:

    Move the right pointer to scan through the string , and update the HashMap;

    If the character is already in the HashMap, then move the left pointer to the right of the same character previously found;

    The two pointers can only move forward; The HashMap stores the last indices of every characters.

Code

class Solution {
    public int lengthOfLongestSubstring(String s) {
        if(s.length() == 0) return 0;
        HashMap<Character, Integer> map = new HashMap<>();
        int maxLength = 0;
        for(int i = 0, j = 0; i < s.length(); i++){
            if(map.containsKey(s.charAt(i))){
                j = Math.max(map.get(s.charAt(i)) + 1, j);
            }
            map.put(s.charAt(i),i);
            maxLength = Math.max(maxLength, i-j+1);
        }
        return maxLength;    
    }
}

Complexity

Time: O(N) 

Space: O(128) only 128 unique characters
falconruo commented 2 years ago

思路: 滑动窗口(双指针)法:

复杂度分析:

代码(C++):

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int n = s.length();

        if (n <= 1) return n;
        // key: character, value: index in string
        map<char, int> mp;
        int l = 0;
        int res = 0;
        for (int i = 0; i < n; ++i) { // i = right boarder, l = left boarder
            if (mp.count(s[i]) && l <= mp[s[i]])
                l = mp[s[i]] + 1;
            res = max(res, i - l + 1);
            mp[s[i]] = i;
        }

        return res;
    }
};
wangzehan123 commented 2 years ago

代码

Java Code:


class Solution {

    public int lengthOfLongestSubstring(String s) {
      HashMap<Character,Integer> hs = new HashMap<>();
      char[] arr = s.toCharArray();
      int left = 0;
      int max = 0;
      for (int i = 0; i < arr.length; i++) {
        if (hs.containsKey(arr[i])) {
          left = Math.max(left, hs.get(arr[i]) + 1);

        }
        hs.put(arr[i], i);
        max = Math.max(max, i - left + 1);
      }
      return max;
    }
  }
rzhao010 commented 2 years ago

Thoughts

  1. Use HashMap or array to count the last shown index of character
  2. Two pointers as slide window to traverse the string

Code

    public int lengthOfLongestSubstring(String s) {
        if (s.length() == 0 || s == null) {
            return 0;
        }
        int left = 0, max = 0;
        Map<Character, Integer> map = new HashMap<>();
        for (int right = 0; right < s.length(); right++) {
            if (map.containsKey(s.charAt(right))) {
                left = Math.max(left, map.get(s.charAt(right)) + 1);
            }
            map.put(s.charAt(right), right);
            max = Math.max(max, right - left + 1);
        }
        return max;
    }

Complexity

LannyX commented 2 years ago

思路

Hash Set

代码

class Solution {
    public int lengthOfLongestSubstring(String s) {
        Set<Character> set = new HashSet<>();
        int maxLen = 0;
        int left = 0;

        for(int i = 0; i < s.length(); i++){
            while(set.contains(s.charAt(i))){
                set.remove(s.charAt(left));
                left++;
            }
            set.add(s.charAt(i));
            maxLen = Math.max(maxLen, i - left + 1);
        }
        return maxLen;

    }
}

复杂度分析

fredxxj commented 2 years ago

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        dic = {}  
        result, last = 0, 0  
        for i in range(len(s)):
            j = dic.get(s[i], -1)
            dic[s[i]] = i
            last = last + 1 if temp < i - j else i - j
            result = max(result, last)
        return result
ZacheryCao commented 2 years ago

Idea:

Sliding windows + Hash Table. The sliding window's right boundary is always updates one by one. Every time when we meet a char has been seen before, we find out the last time we saw it. Compare its position with current sliding window's left boundary. If the left boundary if smaller than that position, we update the left boundary to the one position next to it. No matter whether we update the left boundary or not, we always update the answer to the longest subsequence without the repeat chars

Code:

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        if not s:
            return 0
        ans = 1
        i, j = 0, 0
        lastSeen = {}
        while j < len(s):
            if s[j] in lastSeen and i < lastSeen[s[j]]:
                    i = lastSeen[s[j]]
            lastSeen[s[j]] = j + 1
            ans = max(ans, j -i + 1)
            j += 1
        return ans

Complexity:

Time: O(N) Space: O(N)

qihang-dai commented 2 years ago

O(N) O(N). 哈希记录每一个字符出现的最后的位置,如果出现过了,就将左指针跳到最后出现位置的前一位,遍历中不断计算最大的左右指针差距

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int[] cache = new int[128];
        int res = 0;
        for(int i = 0, j = 0; i < s.length(); i++){
            if(cache[s.charAt(i)] > 0) j = Math.max(j, cache[s.charAt(i)]); //将左指针跳到当前无重复值的最大index。
            cache[s.charAt(i)] = i + 1; //更新最后出现的位置
            res = Math.max(i - j + 1, res);
        }
        return res;
    }
}
zol013 commented 2 years ago
class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        ans = 0
        i = 0
        hashmap = defaultdict(int)

        for j in range(len(s)):
            hashmap[s[j]] += 1
            if hashmap[s[j]] == 1:
                ans = max(ans, j - i + 1)
            else:
                while hashmap[s[j]] > 1:
                    hashmap[s[i]] -= 1
                    i += 1

        return ans

TC: O(N) SC:O(128)

ZhangNN2018 commented 2 years ago

思路

复杂度

代码

class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        if s == '':
            return 0        
        maxlen=1
        flag=0 #重复元素的下标
        for i in range(1,len(s)):
            leng=1
            j=i
            while j > flag:
                if s[i]!=s[j-1]:
                    leng=leng+1 #未出现重复元素,长度加一
                    j=j-1
                else: 
                    flag=j #出现重复的,下一次就从重复元素的下一个开始比较
                    break                   
            maxlen=max(maxlen,leng) 
        return maxlen
Menglin-l commented 2 years ago

approach:hashmap


code:

class Solution {
    public int lengthOfLongestSubstring(String s) {
        if (s == null || s.length() == 0) return 0;

        int left = 0;
        int ans = 0;

        HashMap<Character, Integer> map = new HashMap<>(); // map:<character, index>

        for (int i = 0; i < s.length(); i ++) {
            char c = s.charAt(i);

            if (map.containsKey(c)) {
                if (map.get(c) >= left) {
                    left = map.get(c) + 1;
                }
            }

            ans = Math.max(ans, i - left + 1);
            map.put(c, i);
        }
        return ans;
    }
}

complexity:

Time: O(N)

Space: O(N)

pangjiadai commented 2 years ago

Python3

import collections
class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        # hashmap: {key: char, value: frequency}
        hashmap = collections.defaultdict(int)
        ans = 0
        l = 0 

        for r in range(len(s)):
            # 用while不是if
            while hashmap.get(s[r], 0) != 0:
                hashmap[s[l]] = hashmap.get(s[l], 0) - 1
                l += 1
            hashmap[s[r]] = hashmap.get(s[r], 0) + 1
            ans = max(ans, r-l+1)

        return ans
jiaqiliu37 commented 2 years ago
class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:

        hashmap = defaultdict(int)
        i = 0
        ans = 0

        for j in range(len(s)):
            hashmap[s[j]] += 1

            while hashmap[s[j]] > 1:
                hashmap[s[i]] -= 1
                i += 1

            ans = max(ans, j - i + 1)

        return ans

Time complexity O(n) Space complexity <=O(128)

Courtneyz94 commented 2 years ago
    def lengthOfLongestSubstring(self, s):
        start_pos = 0
        current_pos = -1   
        max_length = 0
        char_pos = {}
        for current_pos in range(len(s)):
            if s[current_pos] in char_pos and char_pos[s[current_pos]] >= start_pos :
                max_length = max(max_length, current_pos - start_pos)
                start_pos = char_pos[s[current_pos]] + 1
            char_pos[s[current_pos]] = current_pos
        return max(max_length, current_pos - start_pos + 1) 
nonevsnull commented 2 years ago

思路

//s6

代码

//s6
class Solution {
    public int lengthOfLongestSubstring(String s) {
        int res = 0, left = 0;
        HashSet<Character> set = new HashSet<>();
        for(int i = 0;i < s.length();i++) {
            char cur = s.charAt(i);

            while(set.contains(cur)){
                char leftChar = s.charAt(left);
                set.remove(leftChar);
                left++;
            }
            set.add(cur);
            res = Math.max(res, set.size());
        }

        return res;
    }
}

复杂度

time: O(N) space: O(N)

pangjiadai commented 2 years ago

Python3

import collections
import heapq
class Solution:
    def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        hashmap = collections.Counter(nums)
        heap = []

        for num, frequency in hashmap.items():
            heapq.heappush(heap, (frequency, num))
            if len(heap) > k:
                heapq.heappop(heap)

        ans = []
        while heap:
            num = heapq.heappop(heap)[1]
            ans.append(num)

        return ans
kbfx1234 commented 2 years ago

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

// 1-2
class Solution {
public:
// 滑动窗口
    int lengthOfLongestSubstring(string s) {
        if (s.size() == 0) return 0;
        unordered_set<char> uset;
        int length = 0;
        int left = 0;
        for (int i = 0; i < s.size(); i++) {
            while (uset.find(s[i]) != uset.end()) {
                uset.erase(s[left]);
                left++;
            }
            uset.insert(s[i]);
            length = max(length, i - left + 1);
        }
        return length;
    }
};
hdyhdy commented 2 years ago

思路: 滑动窗口加哈希表。首先设定好左右窗口位置,其次,让右边一直往前走,直到遇到了哈希表有值的情况就停下来,让左边往前走并删除响应哈希表。用右边减左边 + 1计算窗口大小。

func lengthOfLongestSubstring(s string) int {
    cur := map[byte]int{}
    rk,ans := -1,0
    for i := 0;i < len(s);i ++ {
        if i != 0{
            delete(cur,s[i - 1])
        }
        for rk + 1 < len(s) && cur[s[rk + 1]] == 0{
            cur[s[rk + 1]] = 1
            rk ++ 
        }
        ans = max(ans,rk + 1 - i )
    } 
    return ans 
}

func max(a int, b int) int {
    if a > b{
        return a
    }else {
        return b
    }
}

空间复杂度:字符集大小 时间复杂度:N

ZJP1483469269 commented 2 years ago
class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        n = len(s)
        if n <= 1:
            return n
        l = 0
        ans = 0
        hashmap = {}
        for r in range(0,n):
            if not hashmap.__contains__(s[r]):
                hashmap[s[r]] = True
            else:
                hashmap[s[r]] = not hashmap[s[r]]
            while(hashmap[s[r]]== False):
                hashmap[s[l]] = not hashmap[s[l]]
                l += 1
            ans = max(ans,r-l+1)
        return ans
Zhang6260 commented 2 years ago

JAVA版本

使用hash来充当一个滑动窗口

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int  res = 0;
        int left = 0,right = 0;
        HashSet<Character> set = new HashSet<>();
        while(right<s.length()){
            char temp = s.charAt(right++);
            if(!set.contains(temp)){
                set.add(temp);
            }else{
                while(set.contains(temp)){
                    set.remove(s.charAt(left++));
                }
                set.add(temp);
            }
            res = Math.max(res,set.size());
        }
        return res;

    }
}

时间复杂度:O(n)

空间复杂度:O(n)

Toms-BigData commented 2 years ago

【Day 22】3. 无重复字符的最长子串

思路

用hashmap存储字符串字符出现个数,定义一个双指针,left负责削减头部,right用于判断该字符数量是否超过1,超过1就停下,没超过就继续,最终找到最长无重复字符的子串

golang代码

func lengthOfLongestSubstring(s string) int {
    m := make(map[byte]int,0)
    n := len(s)
    right,ans :=-1,0
    for left :=0; left <n; left++{
        if left !=0{
            delete(m, s[left-1])
        }
        for right+1 <n &&m[s[right+1]] == 0{
            m[s[right+1]]++
            right++
        }
        ans = max(ans, right-left+1)
    }
    return ans
}
func max(x, y int) int {
    if x<y{
        return y
    }
    return x
}

复杂度

时间:O(n) 空间:O(n)

spacker-343 commented 2 years ago

思路

使用双指针形成一个滑动窗口,并用hash表统计窗口内字符数,一旦窗口内某个字符数重复次数超过1了,就移动左边界使该字符重复次数回到1

代码

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int[] hash=new int[128];
        int left=0;
        int res=0;
        for(int right=0; right<s.length(); right++){
            while(hash[s.charAt(right)]==1){
                hash[s.charAt(left)]--;
                left++;
            }
            hash[s.charAt(right)]++;
            res=Math.max(res, right-left+1);
        }
        return res;
    }
}

复杂度

时间复杂度:O(n) 空间复杂度:O(1)

Flower-F commented 2 years ago

解题思路

滑动窗口

代码

/**
 * @param {string} s
 * @return {number}
 */
var lengthOfLongestSubstring = function(s) {
    const len = s.length;
    const set = new Set();
    let left = 0, right = -1, maxLen = 0;

    while (left < len) {
        if (left !== 0) {
            // 移除字符
            set.delete(s[left - 1]);
        }
        while (right + 1 < len && !set.has(s[right + 1])) {
            // 添加字符
            set.add(s[right + 1]);
            // 右指针移动
            right++;
        }
        // 更新答案
        maxLen = Math.max(maxLen, right - left + 1);
        // 左指针移动
        left++;
    }

    return maxLen;
};

复杂度

时间:O(N) 空间:O(N)

GaoMinghao commented 2 years ago

思路

滑动窗口+哈希表

代码

class Solution {
    public int lengthOfLongestSubstring(String s) {
        if(s.equals("")) return 0;
        char[] input = s.toCharArray();
        int i = 0, j = 0, result = 0, temp=0;
        Map<Character, Integer> records = new HashMap<>();
        while(i<input.length && j<input.length) {
            if(records.get(input[j]) == null || records.get(input[j]) < i) {
                records.put(input[j],j);
                j++;
                temp++;
            } else  {
                result = Math.max(temp,result);
                i = records.get(input[j]) + 1;
                records.put(input[j],j);
                j++;
                temp = j - i;
            }
        }
        result = Math.max(temp,result);
        return result;
    }
}

复杂度

时间复杂度 O(N) 空间复杂度 O(N)

baddate commented 2 years ago

题目

https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/

思路

双指针+滑动窗口+hashset,遍历字符串

代码

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        unordered_set<char> cnt;
        int n = s.size();
        int ptr = -1, ans = 0;
        for (int i = 0; i < n; ++i) {
            if (i != 0) {
                cnt.erase(s[i - 1]);
            }
            while (ptr + 1 < n && !cnt.count(s[ptr + 1])) {
                cnt.insert(s[ptr + 1]);
                ++ptr;
            }
            ans = max(ans, ptr - i + 1);
        }
        return ans;
    }
};

复杂度分析

Alexno1no2 commented 2 years ago
# 题解
# 双指针+哈希表
# 遍历字符串,若当前元素在之前出现过,更新左指针
# 当之前出现的元素在左右指针中间,左指针更新为之前元素下标,若不在中间,左指针不变
# 当前元素加入哈希表

# 复杂度分析
# O(N)

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        dic, res, i = {}, 0, -1   #左指针
        for j in range(len(s)):  #右指针
            if s[j] in dic:     #当前元素在之前出现过,更新左指针
                #之前出现过的元素在左右指针中间,左指针更新为之前元素下标,若不在左右指针中间,左指针不变
                i = max(i, dic[s[j]]) 
            dic[s[j]] = j    #将当前元素加入哈希表中
            res = max(res, j - i)   
        return res