无重复字符的最长子串
题目描述:
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 :
输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
提示:
- 0 <= s.length <= 5 * 104
- s 由英文字母、数字、符号和空格组成
解法
- 本题可以看作一个动态规划问题。一个子串可以由起始位置和终止位置确定,在遍历时,一开始起始位置(记作start)自然是0,随着子串长度的增大,新字符可能会出现在子串之中,我们记重复字符的位置是pos,那么加入新字符后,就需要调整起始位置为pos + 1。
- 基于此,我们可以在遍历的同时,使用一个字典来记录字符-索引对,这样对于新字符,就可以简单判断前面是否有重复字符;如果有,获取重复字符的位置pos。值得注意的是,start的位置可能会不断往后调整,但字典不会把start前面的字符信息给清除,所以新的字符可能出现在字典中,但其实并不在当前维护的子串中,因此我们需要比较重复字符的位置pos和当前维护的子串的起始位置start的位置关系:
(1)如果 pos < start,那就说明重复字符不在当前维护的子串之中,不用更改起始位置;
(2)如果pos >= start,那就说明重复字符在当前维护的子串之中,需要把起始位置更新为pos + 1。
总结起来就是,start = max(start, pos + 1)
代码
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
char2pos = {} # key-value: 字符-索引
start, res = 0, 0 # 子串起始位置,最大不重复子串长度
for index, item in enumerate(s):
if item in char2pos:
start = max(start, char2pos[item] + 1)
char2pos[item] = index # 更新或记录字符的当前位置
res = max(res, index - start + 1) # 实时更新最大值
return res
测试结果
执行用时:72 ms, 在所有 Python3 提交中击败了72.86% 的用户
内存消耗:15.1 MB, 在所有 Python3 提交中击败了9.27% 的用户
说明
算法题来源:力扣(LeetCode)