头条1-无重复字符的最长子串
无重复字符的最长子串
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
#思路:不能用动态规划做
#遍历s的每个位置,把上次的字串结果保留在一个遍历myset中
#注意上次的结果字串,没有保留在一个字符串变量中,而是保留在了一个set结构的变量中
#原因是什么呢?方便查找当前待判断位置是否在上一次的结果中。set判断 o(1)
#如果当前待判断位置的字符不在上一次的结果set中,当然好办,当次的结果set=当次的结果set加上当前字符
#如果当前待判断位置的字符已在上一次的结果set中,之前的set里的东西肯定需要删除了,而且至少删除一个,
#那需要删除哪些,删除多少次呢,我们的逻辑来了
#此刻,我们虽然知道当前待判断位置的字符已在上一次的结果set中,但不知道具体位置,
#毕竟我们用了set结构,方便查的同时,牺牲了位置的信息,
#但没关系,我们引入一个need_drop记录位置的变量,
#当需要删除是,原字符串s在need_drop记录上的字符就是该删除的对象,
##而且,可能不只删除一次,所以need_drop需要++,判断当前待判断位置的字符是否仍在已修正的结果set中。
##如在,继续上面逻辑,删除字符串s在need_drop记录上的字符,直至(while)当前待判断位置的字符不在已修正的结果set中
##这样的逻辑后,才把s的当前位置的tmp结果搞定了,再和全局的res结果比较一下。
#上面的讲述是后验的,是看过代码后总结的,
#我觉得思维上,有个难点是我们知道need_drop这个变量在需要删除set中的元素时需要++,
#那么在不删除set中的元素时,need_drop需要改动吗
#如果想明白这点,这题应该再也没有困惑的了,
#答案就是不删除set中的元素时,need_drop不需要改动。
#试想,如果一直不需要删除set中的元素,那么need_drop的位置一定不需要变,
#而一旦需要删除set中的元素,按上面的逻辑,need_drop通过++会自动更新到下一次需要待删除的位置上去。
#就是这样神奇,理解了这点,这题就应该算是没啥疑问的了。
#代码如下:
tmp=0
res=0
my_set=set()
need_drop=0
for i in s:
tmp+=1
while i in my_set:
my_set.remove(s[need_drop])
need_drop+=1
tmp-=1
my_set.add(i)
res=max(res,tmp)
return res