在这个系列的博客中,我们根据LeetCode官方给出的每个题目的出现频率,整理并收录了每个类别里高频出现的题目,从简单到中等再到困难,为你提供解题技巧和最佳实践。我们将介绍常见的算法思想,如贪心算法、动态规划、回溯算法等,希望能帮助你提高算法水平,成为你进入人工智能行业敲门砖。
3. 无重复字符的最长子串(难度3/频率5)
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3,解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: s = "pwwkew"
输出: 3,解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
解题思路
该题是面试频率最高的一题,关于字符串的处理大家一定要好好掌握。注意本题是求最长子串,不是对字符串去重。这道题主要用到思路是:滑动窗口,建议做本题前,先看看我的往期题目的题解:
100道高频LeetCode算法图文题解,滑动窗口之最小长度子数组
什么是滑动窗口?所谓滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。
在本题中实现滑动窗口,主要确定如下三点:
- 窗口内是什么?
- 如何移动窗口的起始位置?
- 如何移动窗口的结束位置?
1)窗口内维护的是一个没有重复字符的队列,比如例题中的 abcabcbb,进入这个队列(窗口)为 abc 满足题目要求,当再进入 a,队列变成了 abca,这时候不满足要求。所以,我们要移动这个队列!
2)移动窗口的起始和结束位置,我们只要把队列的左边的元素移出就行了,直到满足题目要求!一直维持这样的队列,找出队列出现最长的长度时候,求出解!
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
# 第一步,边界条件判断
if not s: return 0
# 第二步,定义窗口和初始化窗口长度为0
window_table = set()
i, j = 0, 0
res = 0
# 第三步,循环遍历判断并调整滑动窗口的左右边界
while j < len(s):
if s[j] not in window_table:
window_table.append(s[j])
j += 1
res=max(res, j-i+1)
else:
window_table.remove(s[i])
i += 1
return res
题目总结
滑动窗口是我们常见的面试问题,整理了滑动窗口的相关题目,大家可以自己做做:
3. 无重复字符的最长子串
30. 串联所有单词的子串
76. 最小覆盖子串
159. 至多包含两个不同字符的最长子串
209. 长度最小的子数组
239. 滑动窗口最大值
567. 字符串的排列
632. 最小区间
727. 最小窗口子序列