给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
示例 4:输入: s = ""
输出: 0来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
分析
- 首先需要注意得是,题目要求得是寻找最长无重复子串,而非子序列(子序列问题比较简单,要求性能时,可参考无重复数字类型题目,即快慢指针)
- 本题解法较多:暴力解、滑动窗口、hash(本题中类似滑动窗口,牺牲空间换时间得方式)
- 下面提供一个滑动窗口算法得模板
//出自Labuladong 算法小抄一书
int left = 0, right = 0;
while (right < s.size())
{ // 增⼤窗⼝
window.add(s[right]);
right++;
while (window needs shrink)
{ // 缩⼩窗⼝
window.remove(s[left]);
left++;
}
}
- 解法一 暴力解
- 暴力解没意思,一般面试或着笔试也过不了
- 解法二 滑动窗口
- 利用上边得模板(是不是感觉很简单)
-
def lengthOfLongestSubstring(self, s: str) -> int: window = [] maxLen = 0 for c in s: if not window or c not in window: window.append(c) else: maxLen = max(maxLen, len(window)) while c in window: window.pop(0) window.append(c) maxLen = max(maxLen, len(window)) return maxLen
- 解法三 hash
- 可看出其实上边得滑动窗口得时间复杂度还是O(N^2),也许in关键字在python中被优化过,例如使用了hash?我们是不是可使用hash来做呢?答案是必须得。
- 消耗了空间,但是将时间复杂度降到了O(N)
-
def lengthOfLongestSubstring(self, s: str) -> int: ret = 0 hash = {} left, right = 0, 0 l = len(s) while right < l: if s[right] in hash and hash[s[right]] >= left: left = hash[s[right]] + 1 hash[s[right]] = right ret = max(ret, right - left + 1) right += 1 return ret