无重复字符的最长子串的两种解决方法

该博客介绍了如何解决LeetCode上的3.无重复字符的最长子串问题。提供了两种解决方案:哈希表法和双指针法。哈希表法通过维护一个哈希表记录字符位置,遇到重复字符时删除之前的字符;双指针法则使用一个左指针固定,右指针探索,遇到重复字符时更新左指针并移除最左侧字符。复杂度分析显示两种方法的时间复杂度均为O(n*max(str_length)),空间复杂度为O(max(str_length))。
摘要由CSDN通过智能技术生成

题目地址(3. 无重复字符的最长子串)

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

题目描述

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



示例 1:

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


示例 2:

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


示例 3:

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




提示:

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

哈希表法

从前向后遍历字符串,用一个哈希表记录不重复字符的位置,如果碰到一个字符已经在哈希表中,就删除重复字符之前的所有字符,每次哈希表中添加新字符,都更新最长不重复的长度

  • 语言支持:Python3

Python3 Code:


class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        #双指针前进
        strLength={}
        max_len=0
        for i in range(len(s)):
            if s[i] not in strLength:
                strLength[s[i]]=i
                max_len=max(max_len,len(strLength))
            else:
                #如果字符串在字典里面了,将这个字典里该字符之前的所有字符删除
                index1=strLength[s[i]]
                listKeys=list(strLength.keys())
                for k1 in listKeys:
                    if strLength[k1]<=index1:
                        del strLength[k1]
                    else:
                        break;
                strLength[s[i]]=i
        return max_len

复杂度分析

令 n 为数组长度。

  • 时间复杂度: O ( n ∗ m a x ( s t r l e n g t h ) O(n*max(str_length) O(nmax(strlength)
  • 空间复杂度: O ( m a x ( s t r l e n g t h ) O(max(str_length) O(max(strlength)

双指针法

关键点

双指针法,其实这方法很好理解,就是一个左指针不断地一个个向前走,每次走动一格,另一个右指针,则负责开拓,这里最关键的是定义好开拓结束条件,也就是出现重复字符,就停止开拓,更新不重复字符长度。然后左指针加一,并从不重复字符中移除最左侧字符。重复上述操作,直至左指针到达最后一个字符就停止

代码

  • 语言支持:Python3

Python3 Code:


class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        #这个题中左指针更多的时候是一个不断前进的固定靶子,每次前进一格,而右指针是一个宽松的向前探索的活动靶子
        strSet=set()
        rightEdge=len(s)
        max_len=0
        rk=-1
        for i in range(len(s)):
            #左指针前进
            if i!=0:
                strSet.remove(s[i-1])
            while rk+1<len(s) and s[rk+1] not in strSet:#右指针探索
                strSet.add(s[rk+1])
                rk+=1
            max_len=max(max_len,rk-i+1)
        return max_len


                
                
            


复杂度分析

令 n 为数组长度。

  • 时间复杂度: O ( n ∗ m a x ( s t r l e n g t h ) ) O(n*max(str_length)) O(nmax(strlength))
  • 空间复杂度: O ( n ∗ m a x ( s t r l e n g t h ) ) O(n*max(str_length)) O(nmax(strlength))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值