本文基于各个大佬的文章
上点关注下点赞,明天一定更灿烂!
前言
Python基础好像会了又好像没会,所有我直接开始刷leetcode一边抄样例代码一边学习吧。本系列文章用来记录学习中的思考,写给自己看的,也欢迎大家在评论区指导~
您的每一条评论都会让我更有学习的动力。
一、分析题目
补充:字串是字符串中连续的非空序列
本题目被划分到了【滑动窗口】分组
滑动窗口(Sliding Window)是一种基于双指针技术的高效算法,专门用于解决数组或字符串的子序列 / 子数组问题。它通过定义一个 "窗口" 来框定处理范围,并通过移动窗口来减少重复计算,从而优化时间复杂度。
分为固定大小窗口和可变大小窗口
滑动窗口与双指针的关系:滑动窗口是双指针技术的特殊应用
特性 | 双指针技术 | 滑动窗口技术 |
---|---|---|
核心思想 | 使用两个指针协同工作 | 使用两个指针定义一个窗口 |
指针关系 | 可以同向、相向或其他关系 | 通常是同向,左指针 <= 右指针 |
应用范围 | 广泛,包括数组、链表等 | 主要用于数组 / 字符串的子序列问题 |
窗口概念 | 不一定有明确窗口概念 | 明确的窗口范围和滑动操作 |
典型应用 | 两数之和、反转数组、环形链表 | 子数组求和、最长子串、字符串匹配 |
滑动窗口技术适合解决的问题:
- 子序列 / 子数组问题:需要处理数组或字符串的连续部分
- 范围查询问题:需要在特定范围内进行计算或判断
- 重复计算问题:暴力解法中存在大量重复计算的问题
- 条件匹配问题:需要找到满足特定条件的子序列
滑动窗口算法的基本步骤
- 初始化窗口:定义左右指针,通常初始化为 0
- 扩展窗口:移动右指针,扩大窗口范围,直到满足特定条件
- 收缩窗口:在满足条件的情况下,尝试移动左指针,缩小窗口范围,优化结果
- 记录结果:在窗口滑动过程中记录满足条件的最优结果
- 滑动窗口:重复步骤 2-4,直到右指针到达数据末尾
""" 初始化 left = 0, result = 初始值 for right in 0..n-1: 加入当前元素到窗口 while 窗口满足条件: 更新result 移除左侧元素,移动left指针 return result """
二、思路以及代码
因为字串是字符串中连续的非空序列,结合样例3
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
所以不能简单的在原有字符串的基础上做去重操作
因为最长字串的长度不一定为多少,所以这是一个可变长度窗口问题。
思路:
- 使用左右指针定义窗口范围,初始时左右指针都指向字符串开头
- 右指针右移扩大窗口,将字符加入窗口
- 使用哈希表记录每个字符最后出现的位置
- 如果遇到重复字符,将左指针移动到重复字符的下一个位置
- 不断更新最大窗口长度
right | 当前字符 | 操作 | 说明 |
---|---|---|---|
0 | 'a' | 'a' 不在字典中,加入:char_index['a']=0 | 最大子串变为 "a" ,长度1 |
1 | 'b' | 'b' 不在字典中,加入:char_index['b']=1 | 子串 "ab" ,长度2 |
2 | 'c' | 'c' 不在字典中,加入:char_index['c']=2 | 子串 "abc" ,长度3 |
3 | 'a' | 'a' 已在字典,位置0,且 >= left=0 ,表示重复 |
移动 更新 计算最大长度: |
4 | 'b' | 'b' 在字典位置1 >= left=1 ,重复 |
更新 计算最大长度: |
5 | 'c' | 'c' 在字典位置2 >= left=2 ,重复 |
更新 计算最大长度: |
6 | 'b' | 'b' 在字典位置4 >= left=3 |
更新 计算最大长度: |
7 | 'b' | 'b' 在字典位置6 >= left=5 |
更新 计算最大长度: |
最后,最长不重复子串长度为 3。
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
# 初始化左指针和最大长度
left = 0
max_length = 0
# 创建空哈希表(字典),用于记录字符最后出现的位置
char_index = {}
# 右指针遍历字符串
for right in range(len(s)):
current_char = s[right]
# 如果字符已在当前窗口中出现,移动左指针到重复字符的下一个位置
if current_char in char_index and char_index[current_char] >= left:
left = char_index[current_char] + 1
# 更新字符最后出现的位置
char_index[current_char] = right
# 更新最大长度
current_length = right - left + 1
if current_length > max_length:
max_length = current_length
return max_length
运行一下,啦啦啦
三、本题收获
学习了双指针的进阶用法,而且也算是复习了哈希表
总结
只会打暴力,基础一团糟,明天再学吧老铁,别真学会了。