[leetcode刷题]Day3:3. 无重复字符的最长子串【滑动窗口算法】

一、题目

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

示例 1:

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

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

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/longest-substring-without-repeating-characters
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、题解

方法一

思路:

使用遍历字符串同时记录该子串之前遇到的字符与之前的子串长度,若遇到重复字符则更新最大无重复字串的长度并且将当前字串长度重置重新开始从上一次遇到重复字符的后一个字符位置遍历字符串。

这其中最重要的就是查找当前遍历到的字符与该子串之前记录的字符是否重复,如果遍历查找则查找时间复杂度为O(n),所以采用哈希表,哈希表的查找时间复杂度为O(1)。

代码:

class Solution():
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        current_len=0
        memory_num={}#记录子串
        max_len=0
        header_pointer=0
        
        
        while(header_pointer<len(s)):
            for i,each_char in  enumerate(s[header_pointer:]):
                
                #若当前字符没重复
                if(memory_num.get(each_char)==None):
                    memory_num[each_char]=i+header_pointer
                    current_len+=1
                    #如果遍历到底
                    if(header_pointer+i>=len(s)-1):
                        max_len=max(max_len,current_len)
                        return max_len

                else:
                    #否则将指针移动到上次遇到该字符的位置后一个并且退出for循环
                    header_pointer=memory_num[each_char]+1
                    memory_num.clear()
                    
                    #更新最长长度并且重置当前长度
                    max_len=max(current_len,max_len)
                    current_len=0
                    break
        #若最后一个重复了
        max_len=max(max_len,current_len)
        return max_len

结果

时间消耗上结果并不理想

方法二(滑动窗口算法)

思路

在使用哈希表查找的基础上,维持一个滑动窗口,由左右指针指示。

相当于问从一个字符开始能获得的最长字串长度为多少,然后分别询问之后的字符从其开始的最长字串长度是多少,若长于已经记录的max_len就更新max_len

 证明:若一个从字符的位置开始右指针右移直到移动到指向与当前字串有重复字符的位置,左指针不动,则左指针移动到当前左右指针中字串的那个重复字符索引+1的索引位置前,左指针指向的字符开始的最长字串一定小于最初的右指针位置减去左指针位置的值。

因为在左指针移动到当前左右指针中字串的那个重复字符索引+1的索引位置前,左指针的字符开始到右指针的前一个字符结束的字串一定有一个字符与右指针指向的字符重复,而左指针右移减少了左右指针之间的距离。

由于左右指针最多遍历一次字符串,时间复杂度为O(n)

代码

class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        if(len(s)==0):
            return 0
        
        left_pointer=0
        right_pointer=0
        max_len=0
        hashmap={}
        while(right_pointer<len(s)):
            if(hashmap.get(s[right_pointer])==None):
                hashmap[s[right_pointer]]=0
                right_pointer+=1
            else:
                del hashmap[s[left_pointer]]
                left_pointer+=1
            max_len=max(right_pointer-left_pointer,max_len)
        return max_len

结果

 可见时间上获得了巨大优化

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值