描述
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是子串的长度,"pwke" 是一个子序列,不是子串
答案
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
#存放非重复的dict
longest_sub = dict()
# 目前窗口最大数
max_len = 0
# 窗口左边位置,因可能没有元素,所以左边位置初始值为0
left_point = 0
for index, charactor in enumerate(s):
if charactor in longest_sub:
# 出现重复元素,更新窗口的左边位置,因为重复的元素不能要,所以把左边首次出现重复元素的位置定义为窗口左边位置
left_point = max(left_point, longest_sub[charactor])
#当最左边窗口到字符串末尾的长度小于最长无重复子串,就可以跳出循环了。
if(len(s)-left_point<=max_len):
break
# 窗口右边位置(一旦进入循环,说明字符不为空,那么最少右边是1)
right_point = index+1
# 窗口(字符作为key,位置作为值)
longest_sub[charactor] = right_point
# 目前窗口最大长度
max_len = max(max_len, right_point - left_point)
return max_len
思路
为方便理解算法,现在我们来玩一把贪吃蛇的游戏。
- 最暴力的写法就是把所有该字符串的子字符串都遍历出来,然后从里面找出没有重复字符的最大字符串
- 我们可以想象这样一条贪吃蛇,从最左边(0位置)开始,张嘴就吃下不同的字符。一直这么吃,蛇越来越长,直到吃到了相同的字符,就不能吃了。这就是贪吃蛇目前能达到的最大长度。
- 下次再吃,可以从哪里吃?可以从相同字符的上次出现的位置后面一位开始吃。这里我们为了方便就不回头吃了,直接把蛇尾巴放在那,继续往后面吃就可以了。
- 什么时候可以停下来呢?吃完?不一定吧。蛇如果吃到相同字符,当蛇尾巴到字符串的结尾的长度比现在最长的贪吃蛇短,那么就可以不吃了。
重点
- python dict key 是不能重复的。
- 思路的理解是本算法的重点