3-无重复字符的最长子串
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
首先想到的就是遍历。
从头到尾,每一个位置i,都向后搜索到len(s)的位置,然后用一个set保存不重复的值,如果出现重复值则退出本次循环,重置一些状态,返回set中元素的个数,就是本次找到的最长子串。
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
lenList = []
currentLen = 0
sss = set()
for i in range(len(s)):
for j in range(i, len(s)):
if s[j] in sss:
lenList.append(currentLen)
currentLen = 0
sss.clear()
break
else:
sss.add(s[j])
currentLen += 1
if j == len(s)-1:
lenList.append(currentLen)
currentLen = 0
sss.clear()
break
return max(lenList) if len(lenList)!=0 else 0
显然,双层循环,时间复杂度为O(n²)
进阶(滑动窗口)
现在假设我们有一个可伸缩的长方形的框,初始长度是1,然后我们拿这个框,从头去套我们的字符串。
那么如果框中没有重复值,我们就更新最大长度,然后框的长度+1,如果加1后框中无重复值,则重复上述操作。最后返回最大值。
若果遇到重复值,则只要将我们的框,从上一个这个值出现的位置的后一位截取到最后,即可。
这样只需要进行一次遍历。时间复杂度为O(n)
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
if s == "":
return 0
maxLen = 0
currentLen = 1
sss = []
for i in s:
if i not in sss:
sss.append(i)
maxLen = max(currentLen, maxLen)
else:
sss = sss[sss.index(i)+1:]
sss.append(i)
currentLen = len(sss)
currentLen += 1
return maxLen
O(n)的时间效率当然是比O(n²)高出不少的。