学习目标:
- 掌握几种基本的算法结构,实现算法问题解决的基本思维
学习内容:
给定一个字符串 s
,请你找出其中不含有重复字符的 最长连续子字符串 的长度。
示例 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
由英文字母、数字、符号和空格组成
题解明细:
套用下面的模版:
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
# 定义需要维护的变量, 求最大长度,定义max_len, 该题又涉及去重,需要一个哈希表
max_len, hashmap = 0, {}
# 定义窗口的首尾端 (start, end), 然后滑动窗口
start = 0
for end in range(len(s))
# 更新需要维护的变量 (max_len, hashmap)
# 把窗口末端元素加入哈希表,使其频率加1,并且更新最大长度
hashmap[s[end]] = hashmap.get(s[end], 0) + 1
if len(hashmap) == end - start + 1:
max_len = max(max_len, end - start + 1)
# 窗口长度可变: 这个时候一般涉及到窗口是否合法的问题
# 这时要用一个while去不断移动窗口左指针, 从而剔除非法元素直到窗口再次合法
# 当窗口长度大于哈希表长度时候 (说明存在重复元素),窗口不合法
# 所以需要不断移动窗口左指针直到窗口再次合法, 同时提前更新需要维护的变量 (hashmap)
while end - start + 1 > len(hashmap):
head = s[start]
hashmap[head] -= 1
if hashmap[head] == 0:
del hashmap[head]
start += 1
# Step 5: 返回答案 (最大长度)
return max_len
思路2:
把字符串从index0开始切片得到str1,然后str1 转list,然后循环list判断非相同index的值不相等。
成功输出最大长度=当前index,失败直接break
最新的循环结构跟之前的最大长度对比,取最大的
思路3:暴力一点,直接用集合,反正集合有唯一值的特性
我解答的时候就是用的集合的思路,加上遍历
学习笔记:
思路是:滑动窗口
1、滑动窗口原理:
就是一个队列,比如例题中的 abcabcbb,进入这个队列(窗口)为 abc 满足题目要求,当再进入 a,队列变成了 abca,这时候不满足要求。所以,我们要移动这个队列。
2、滑动窗口思维框架&此类题目解题思路:
初始时,左右指针left,right都指向第0个元素,窗口为[left,right),注意这里是左闭右开,因此初始窗口[0,0)区间没有元素,符合我们的初始定义
开始循环遍历整个数组元素,判断当前right指针是否超过整个数组的长度,是退出循环,否则执行第3步
然后right指针开始向右移动一个长度,并更新窗口内的区间数据
当窗口区间的数据满足我们的要求时,右指针right就保持不变,左指针left开始移动,直到移动到一个不再满足要求的区间时,left不再移动位置
- 执行第2步
框架模版 (伪代码):
class Solution:
def problemName(self, s: str) -> int:
# 定义需要维护的变量们 (对于滑动窗口类题目,这些变量通常是最小长度,最大长度,或者哈希表)
x, y = ..., ...
# 定义窗口的首尾端 (start, end), 然后滑动窗口
start = 0
for end in range(len(s)):
# 更新需要维护的变量, 有的变量需要一个if语句来维护 (比如最大最小长度)
x = new_x
if condition:
y = new_y
'''
------------- 下面是两种情况,根据题意二选1 -------------
'''
# 情况1
# 如果题目的窗口长度固定:用一个if语句判断一下当前窗口长度是否达到了限定长度
# 如果达到了,窗口左指针前移一个单位,从而保证下一次右指针右移时,窗口长度保持不变,
# 左指针移动之前, 先更新Step 1定义的(部分或所有)维护变量
if 窗口长度达到了限定长度:
# 更新 (部分或所有) 维护变量
# 窗口左指针前移一个单位保证下一次右指针右移时窗口长度保持不变
# 情况2
# 如果题目的窗口长度可变: 这个时候一般涉及到窗口是否合法的问题
# 如果当前窗口不合法时, 用一个while去不断移动窗口左指针, 从而剔除非法元素直到窗口再次合法
# 在左指针移动之前更新Step 1定义的(部分或所有)维护变量
while 不合法:
# 更新 (部分或所有) 维护变量
# 不断移动窗口左指针直到窗口再次合法
# Step 5: 返回答案
return ...
//可能刚开始看不懂,那就是mode问题,在我们做这道题前先用这个模板先套一道简单题【643. 子数组最大平均数 】
如果套完还不懂,不要担心,再套一道,套完仍然不懂,let's 再套一道......
我们有共13 (12中1简) 道题,请相信自己,套着套着,咱们终究会弄懂的
//类题明细:
643. 子数组最大平均数 I
3. 无重复字符的最长子串
159. 至多包含两个不同字符的最长子串
209. 长度最小的子数组
1695. 删除子数组的最大得分
438. 找到字符串中所有字母异位词
567. 字符串的排列
487. 最大连续1的个数 II
1004. 最大连续1的个数 III
1208. 尽可能使字符串相等
1052. 爱生气的书店老板
1423. 可获得的最大点数
1151. 最少交换次数来组合所有的 1
学习产出:
- CSDN 技术笔记 1遍
- CSDN
- leetcode 题目闭环 1个
- . - 力扣(LeetCode)
- nowcoder 题目闭环 1 个
- 最长无重复子数组_牛客题霸_牛客网