LeetCode 刷题记录 |003:无重复字符的最长子串

题目

image.png

审题

今天这道题,看起来是否是很简单?ide

但作为一道中等难度的题目,它可不会让你失望。敲起你的键盘,试着来解下这道题,你会很难找到一个好的思路。学习

事实上,想这个思路也确实花了我很多的时间,是写代码时间的好几倍。spa

首先,要理解 子串 和 子序列 的区别。3d

子串:必须同时具有,连续性和惟一性。
子序列:只须具有惟一性便可。code

个人版本

先说下个人思路。blog

假设一个字符串的长度是10,那我就先从字符串的[0,1]子串查起,假如子串里没有重复字符(经过set()去重查看),就继续查看子串[0,2],若是仍是没有重复,就继续查看[0,3],这时候,咱们发现这个子串里有重复字符(比方说,子串"abcb"),接下来,咱们就要找出是在重复的那个字符的索引(查出是 b,在索引 处)。那下次咱们查找的子串就不是[0,5]了,而是[2,5],就这样一直往下,直到遍历完整个字符串。索引

class Solution:
   def lengthOfLongestSubstring(self, s):
       if len(s) == 1:
           return 1

       reset_start= False
       start = 0
       max_len = 0

       for i in range(len(s)):
           # reset_start就为True,须要从新设置起点
           if reset_start:
               start = new_start

           # 为何加1,是由于第一次start会和end同样是0
           end = i + 1
           sub_str = s[start:end]
           len_sub_str= end - start

           if len(set(sub_str)) != len_sub_str:
               # 找出是在哪一个位置重复
               rep_index = sub_str.index(s[i])
               new_start = rep_index + start + 1
               reset_start= True
               continue

           if len_sub_str > max_len:
               # 记录下迄今为止最在长度
               max_len = len_sub_str
           skip = False

       return max_len

运行一下,结果不好。只击败了24.73%。今天吃不了鸡腿了。不太小明真的是尽力了。只能想到这个思路。
ip

image.png

网上的版本

按照惯例,还得上网去学习别人的优秀代码。ci

真是惊叹,果真是思路决定出路啊。字符串

这种解法很巧妙。

定义两个变量longestleftlongest用于存储最长子字符串的长度,left存储无重复子串左边的起始位置。

而后建立一个哈希表,遍历整个字符串,若是字符串没有在哈希表中出现,说明没有遇到过该字符,则此时计算最长无重复子串,当哈希表中的值小于left,说明left位置更新了,须要从新计算最长无重复子串。每次在哈希表中将当前字符串对应的赋值加1。

class Solution(object):
   def lengthOfLongestSubstring(self, s):
       longest = 0; left = 0; tmp = {}

       for index, each in enumerate(s):
           if each not in tmp or tmp[each] < left:
               # 计算当前最长的长度
               longest = max(longest, index - left + 1)
           else:
               left = tmp[each]
           tmp[each] = index + 1

       return longest

运行一下,看看吧,击败了92.3%。众望所归啊。 佩服佩服。

image.png

总结

其实个人思路,和上面那个优秀代码的思路是一致的。

我作得很差的一点是,在检测当前子串是否重复这一点上面,我选了一个效率很是低的作法,就是每次循环都要计算下len(set(str_obj)) 和 len(str_obj),而这种是至关耗时的,并且会随着字符串长度的增加,耗时也线性增长。

而聪明的人,则是经过维护一个字典,来存放惟一值,和惟一值的最大索引。对执行速度的提高,能够说是很是显著的。

相关文章
相关标签/搜索