每日一题:3.无重复字符的最长子串
1、题目
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
示例 4:
输入: s = ""
输出: 0
提示:
0 <= s.length <= 5 * 104
s 由英文字母、数字、符号和空格组成
2、解法1:前后指针滑动
思路:以某个字符起始的最大无重复字符串
固定前指针,计算以 前指针位置字符起始的最大非重复字符串的长度,如果后指针指向的值存在于该窗口内,说明后续就不用考虑以前指针开始的字符串了,因为他们可能会有重复字符串。
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
length = len(s)
if length==0 or length==1:
return length
maxLen = 1
beginIndex = 0
for endIndex in range(1, length):
sValue = s[endIndex]
if sValue in s[beginIndex:endIndex]:
duplicateIndex = s[beginIndex:endIndex].rfind(sValue) + beginIndex # 寻找窗口内和sValue重复最右侧的索引,
tmpLen = endIndex - beginIndex
beginIndex = duplicateIndex + 1 # 不用在考虑以前面beginIndex开始的字符串了
else:
tmpLen = endIndex - beginIndex + 1
maxLen = tmpLen if tmpLen > maxLen else maxLen
return maxLen
注:上面调用了函数:字符是否存在字符串内 以及 rfind函数,时间复杂度也不低。但是该方法在leetcode上ac了。
显示详情
执行用时:64 ms, 在所有 Python3 提交中击败了84.85%的用户
内存消耗:15 MB, 在所有 Python3 提交中击败了32.31%的用户
3、解法2:滑动窗口
思路:以某个字符起始的最大无重复字符串
思路和解法1类似,只是实现时借助集合来降低时间复杂度。
借助集合从左至右滑动窗口,判断滑动窗口右侧元素是否位于窗口内,如果位于,那么需要更新集合,并增加滑动窗口左侧索引。
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
length = len(s)
if length == 0:
return length
lookup = set()
lookup.add(s[0])
maxLen = 1
beginIndex = 0
for i in range(1, length):
value = s[i]
if value not in lookup:
tmpLen = i - beginIndex + 1
maxLen = tmpLen if tmpLen>maxLen else maxLen
else:
while value in lookup:
lookup.remove(s[beginIndex])
beginIndex += 1
lookup.add(value)
return maxLen
执行用时:60 ms, 在所有 Python3 提交中击败了91.22%的用户
内存消耗:15 MB, 在所有 Python3 提交中击败了24.24%的用户