编程艺术0003_无重复字符的最长子串_解法

Posted 极智视界

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了编程艺术0003_无重复字符的最长子串_解法相关的知识,希望对你有一定的参考价值。

欢迎关注我的公众号 [极智视界],获取我的更多笔记分享

和大家一起 coding,享受 coding 的乐趣

  大家好,我是极智视界。本文分享 0003_无重复字符的最长子串 的多语言解法,包括 C++、C、python、go、java、js。

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

  github 题解链接:https://github.com/Jeremy-J-J/leetcode

文章目录

1、题目描述

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

示例1

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

示例二

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

示例三

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

提示:

  • 0 <= s.length <= 5 * 104
  • s 由英文字母、数字、符号和空格组成

2、题解

2.1 C++

1> 哈希集合 滑动窗口

  • 执行用时 20ms,在所有 C++ 提交中击败了 57.24% 的用户
  • 内存消耗 10.5 MB,在所有 C++ 提交中击败了 42.32% 的用户
class Solution 
public:
    int lengthOfLongestSubstring(string s) 
        unordered_set<char> hashSet;        // 哈希集合
        int n = s.size();
        int ri = 0;        // 右指针 初始值为0
        int res = 0;
        for(int li = 0; li < n; ++li)        // 枚举左指针位置
            while(ri < n && !hashSet.count(s[ri]))     // 不断移动右指针
                hashSet.insert(s[ri]);
                ++ri;
            
            res = max(res, ri - li);
            hashSet.erase(s[li]);     // 左指针向右移动 移除一个字符
        
        return res;
    
;

2.2 C

1> 找相邻两个相同字符间相距的最大长度 滑动窗口

  • 执行用时 0 ms,在所有 C 提交中击败了 100.00% 的用户
  • 内存消耗 5.7 MB,在所有 C 提交中击败了 82.46% 的用户
int lengthOfLongestSubstring(char * s)
    int sLen = strlen(s);
    int left=0, res=0, cnt=0;
    int tmp[128] = 0;
    // 找相邻两个相同字符间相距的最大长度
    for(int i=0; i<sLen; ++i)
        if(0 == tmp[s[i]])      // 滑动右窗
            tmp[s[i]]=1;
            cnt++;
            if(cnt>res)
                res = cnt;
            
        
        else                    // 滑动左窗
            tmp[ s[left++] ] = 0;
            cnt--;
            i--;
        
    
    return res;

2.3 Python

1> 集合 滑动窗口

  • 执行用时 64 ms,在所有 Python 提交中击败了 75.23% 的用户
  • 内存消耗 15 MB,在所有 Python 提交中击败了 82.63% 的用户
class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        hashSet = set()    # 集合
        n = len(s)
        ri = 0      # 右指针 初始值为0
        res = 0
        for li in range(n):   # 枚举左指针位置
            while ri < n and s[ri] not in hashSet:   # 不断移动右指针
                hashSet.add(s[ri])
                ri += 1
            res = max(res, ri - li)
            hashSet.remove(s[li])    # 左指针向右移动 移除一个字符
        return res

2.4 go

1> 哈希集合 滑动窗口

  • 执行用时 12 ms,在所有 go 提交中击败了 38.50% 的用户
  • 内存消耗 2.6 MB,在所有 go 提交中击败了 74.93% 的用户
func lengthOfLongestSubstring(s string) int 
    hashSet := map[byte]int     // 哈希集合
    n := len(s)
    ri := 0      // 右指针 初始值为0
    res := 0
    for li := 0; li < n; li++        // 枚举左指针位置
        for ri < n && hashSet[s[ri]] == 0      // 不断移动右指针
            hashSet[s[ri]]++
            ri++
        
        res = max(res, ri - li)
        delete(hashSet, s[li])    // 左指针向右移动 移除一个字符
    
    return res


func max(x, y int) int 
    if x < y 
        return y
    
    return x

2.5 java

1> 哈希集合 滑动窗口

  • 执行用时 5 ms,在所有 java 提交中击败了 60.28% 的用户
  • 内存消耗 41.8MB,在所有 java 提交中击败了 19.53% 的用户
class Solution 
    public int lengthOfLongestSubstring(String s) 
        HashSet<Character> hashSet = new HashSet<Character>();    // 哈希集合
        int n = s.length();
        int ri = 0;     // 右指针 初始值为0
        int res = 0;
        for(int li = 0; li < n; ++li)    // 枚举左指针位置
            while(ri < n && !hashSet.contains(s.charAt(ri)))     // 不断移动右指针
                hashSet.add(s.charAt(ri));
                ++ri;
            
            res = Math.max(res, ri - li);
            hashSet.remove(s.charAt(li));       // 左指针向右移动 移除一个字符
        
        return res;
    

2.6 js

1> 哈希集合 滑动窗口

  • 执行用时 76 ms,在所有 javascript 提交中击败了 82.46% 的用户
  • 内存消耗 46.1MB,在所有 javaScript 提交中击败了 40.02% 的用户
/**
 * @param string s
 * @return number
 */
var lengthOfLongestSubstring = function(s) 
    const hashSet = new Set();    // 哈希集合
    const n = s.length;
    let ri = 0;     // 右指针 初始值为0
    let res = 0;
    for(let li = 0; li < n; ++li)     // 枚举左指针位置
        while(ri < n && !hashSet.has(s.charAt(ri)))     // 不断移动右指针
            hashSet.add(s.charAt(ri));
            ++ri;
        
        res = Math.max(res, ri - li);
        hashSet.delete(s.charAt(li));    // 左指针向右移动  移除一个字符
    
    return res;
;

  好了,以上分享和整理了 0003_无重复字符的最长子串 的多语言解法,希望我的分享能对你的学习有一点帮助。


 【公众号传送】

《【编程艺术】0003_无重复字符的最长子串_解法》


扫描下方二维码即可关注我的微信公众号【极智视界】,获取我的更多经验分享,让我们用极致+极客的心态来迎接AI !

以上是关于编程艺术0003_无重复字符的最长子串_解法的主要内容,如果未能解决你的问题,请参考以下文章

编程练习:无重复字符的最长字串

最长公共子串_暴力解法(不会正解)

leetcode-python-03无重复字符的最长子串

leetcode-python-03无重复字符的最长子串

5-101-(LeetCode- 3) 无重复字符的最长子串

LeetCode-003-无重复字符的最长子串