3. Longest Substring Without Repeating Characters 无重复字符的最长子串

1. 原始题目

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

示例 1:

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

示例 2:

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

示例 3:

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

2. 思路

双指针法。[i,j]左闭又闭区间为当前子串,如果j+1位置的元素没有重复则继续加入,否则i+1直到没有重复元素。那么如何确定是否重复呢,有两种方法,第一种是循环判断在字串中是否仍有重复的元素。第二种是构建一个字典,来判断当前元素是否已经出现过。下面给出了两种解法。

3. 解题

方法1.循环判断是否有重复

 1 class Solution:
 2     def lengthOfLongestSubstring(self, s: str) -> int:
 3         if not s:return 0
 4         i,j=0,0      # 单元素肯定是目前的最长子串
 5         res = 1      # 此时长度为1 
 6         temp = s[0]  # 子串
 7         while(i<len(s) and j+1<len(s)):
 8             if s[j+1] in temp:        # 如果下一个元素有重复
 9                 while(s[j+1] in temp):  # 则i循环往前直到不包含该重复元素
10                     i+=1
11                     temp = temp[1:]
12             else:   
13                 j+=1                 # 没有重复元素就继续往前
14                 temp+=s[j]
15                 res = max(len(temp),res)       # 返回最长的子串长度
16            
17         return res

 

方法2.利用字典判断当前元素是否有重复

 1 from collections import defaultdict
 2 class Solution:
 3     def lengthOfLongestSubstring(self, s: str) -> int:
 4         if not s:return 0
 5         d = defaultdict(int)
 6         i,j=0,-1   # [i,j]     左闭又闭区间为初始子串
 7         res = 0
 8         while(i<len(s)): 
 9             if j+1<len(s) and d[s[j+1]]==0:   # 如果j+1个元素没有出现过,则j继续+1 
10                 j+=1
11                 d[s[j]]+=1
12             else:                             # 出现过则i位置字典对应的次数-1,i右移  
13                 d[s[i]]-=1
14                 i+=1
15             res = max(res,j-i+1)
16 
17         return res

 

posted @ 2019-05-02 10:08  三年一梦  阅读(168)  评论(0编辑  收藏  举报