LeetCode 3. 无重复字符的最长子串(中)
Posted tonydandelion2014
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 3. 无重复字符的最长子串(中)相关的知识,希望对你有一定的参考价值。
3. 无重复字符的最长子串(中)
题目
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
考察知识点
队列、滑动窗口
核心思想
遍历字符串,找到不重复的部分,记录下来,输出最长的那一个。
图示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WleV1bRr-1583596773087)(http://q3q41dfs4.bkt.clouddn.com/20ahe.gif)]
Python代码
class Solution:
def lengthOfLongestSubstring(self, s):
max_length = 0 # 开始位置
d = # 保存字符出现位置
start = 0 # 当前最大字串的开始位置 也就是滑动窗口的左边缘
for i in range(len(s)):
if s[i] in d and start <= d[s[i]]:
# 如果该字符串出现过 且 当前最大字串的开始位置(start)小于等于该字符串之前出现的位置
start = d[s[i]] + 1 # 当前重复字符串上一次出现位置的下一个位置 被设置为 新的最大字串搜寻开始位置 也就是滑动窗口的左边缘
max_length = max(i-start+1, max_length) # i-start+1(当前位置(i)减去滑动窗口左边缘的间距,也就是新字串的长度)
d[s[i]] = i # 全部计算完成之后,更新这个字串出现位置。
return max_length
print("leet code accept!!!")
cases = ["abcabcbb", "bbbbb", "pwwkew", "aabaab!bb", "nfpdmpi", "dvdf"]
answer = ["abc", 'b', 'wke', "ab!", 'nfpdm', 'vdf']
if __name__ == "__main__":
solution = Solution()
for i in range(len(cases)):
print(solution.lengthOfLongestSubstring(cases[i])==len(answer[i]))
- 另一个版本
class Solution3:
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
from collections import defaultdict
d = defaultdict(int) # defaultdict本质就是一个dict
l = ans = 0 # l是当前的最大长度
for i,c in enumerate(s):
while l > 0 and d[c] > 0: # l>0说明不再是第一个字符 d[c]>0说明这个字符不是第一次出现
# 下面这段while循环 会执行l次且直到将c的次数减为0
# 实际上就是把队列左边的元素移出去 平移整个
d[s[i-l]] -= 1
l -= 1 # 当前长度减去1
d[c] += 1 # 记录最新发现的字符
l += 1 # 记录最新长度
ans = max(ans, l)
return ans
类似问题
- 最小覆盖子串
以上是关于LeetCode 3. 无重复字符的最长子串(中)的主要内容,如果未能解决你的问题,请参考以下文章