Leetcode_3. Longest Substring Without Repeating Characters 求一个字符串中最长不重复子串的长度(移动窗口法)

题目:

Given a string, find the length of the longest substring without repeating characters.

Example 1:

Input: "abcabcbb"
Output: 3 
Explanation: The answer is "abc", with the length of 3. 

Example 2:

Input: "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.

Example 3:

Input: "pwwkew"
Output: 3
Explanation: The answer is "wke", with the length of 3. 
             Note that the answer must be a substring, "pwke" is a subsequence and not a substring.

 

代码:方法一:i和j确定窗口的两侧,如果当前元素在字典中,i加; 如果当前元素不在列表中,j加。字典的元素始终为i到j之间的元素。

class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """ 
        
        n = len(s)
        dic = {}
        result = 0
        i = j = 0
        # 滑动窗口思想:i和j确定窗口的两侧,如果当前元素在字典中,i加; 如果当前元素不在列表中,j加。字典的元素始终为i到j之间的元素。
        while i < n and j < n : 
            if s[j] in dic :
                dic.pop(s[i])          #窗口滑动,i+,从窗口移除之前i所指的元素
                i = i + 1
            else :
                dic[s[j]] = j
                result = max(result, j-i+1)
                j = j + 1
        return result

 

方法二:所有元素入窗口(由j遍历),如果重复,更新i为重复元素的位置

class Solution(object):
    def lengthOfLongestSubstring(self, s):
         n = len(s)
        dic = {}
        result = 0
        i = j = 0
        # 滑动窗口思想:i和j确定窗口的两侧,每个元素都入字典,值为元素的下标(如果重复,更新键值),如果重复,则更新i,将i赋值为重复元素的下标
        while j < n :
            if s[j] in dic :
                i = max(dic[s[j]]+1, i)    #这里取max值是确保类似abba这样的,再次重复的元素a所指下标在之前重复元素b的前面,这时dic[s[j]]+1 < i,此时i要取最大值,跳过之前所有重复的元素。  这里i不能取i+1,而dic[s[j]]要取+1,因为重复的时候,dic[s[j]]指的是左边那个重复元素下标,下标+1就跳过了重复;而这里取i值是第二次出现重复,此时这个重复的元素在dic[s[j]]前面,而i大于dic[s[j]],相当于i已经大于当前这个重复元素的下标,已经跳出了重复,不能再+1了,否则就漏掉了不重复元素
            dic[s[j]] = j
            result = max(result, j-i+1)
            j = j + 1
        return result

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值