leetcode:滑动窗口----3. 无重复字符的最长子串

ops/2024/10/16 2:26:56/

给定一个字符串 s ,请你找出其中不含有重复字符的 最长

子串

 的长度。

示例 1:

输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:

输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:

输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

提示:

  • 0 <= s.length <= 5 * 104
  • s 由英文字母、数字、符号和空格组成

因为s由英文字母、数字、符号和空格组成,符合ASCII码,故采用ASCII码大小的数组,使用ASCII码为下标,记录每个字符出现的最后位置。并在每次循环的开始,将left更新为上一次该字符出现的位置+1。

滑动窗口算法的基本原理:

  1. 初始化窗口:定义两个指针,通常是leftright,并初始化为字符串或数组的起始位置。

  2. 滑动窗口right指针逐个增加,尝试扩大窗口,同时更新解的答案。

  3. 更新解的答案:当满足题目条件时,我们需要更新当前的最优解。

  4. 收缩窗口:如果当前窗口不满足题目的条件,移动left指针缩小窗口,直到满足条件为止。

示例分析:

以题目"abcabcbb"为例,详细步骤如下:

  1. 初始化:left = 0, right = 0, maxLen = 0, charIndex[] = {-1, -1, -1, ...}

  2. right逐个增加:

    • s[0] = 'a'charIndex['a'] = -1,更新为charIndex['a'] = 0,窗口长度为1maxLen = 1
    • s[1] = 'b'charIndex['b'] = -1,更新为charIndex['b'] = 1,窗口长度为2maxLen = 2
    • s[2] = 'c'charIndex['c'] = -1,更新为charIndex['c'] = 2,窗口长度为3maxLen = 3
    • s[3] = 'a'charIndex['a'] = 0,左指针移动到1,窗口变为"bca",窗口长度为3maxLen保持不变。
    • s[4] = 'b'charIndex['b'] = 1,左指针移动到2,窗口变为"cab",窗口长度为3maxLen保持不变。
    • s[5] = 'c'charIndex['c'] = 2,左指针移动到3,窗口变为"abc",窗口长度为3maxLen保持不变。
    • s[6] = 'b'charIndex['b'] = 1,左指针移动到4,窗口变为"bca",窗口长度为3maxLen保持不变。
    • s[7] = 'b'charIndex['b'] = 1,左指针移动到5,窗口变为"cab",窗口长度为3maxLen保持不变。

最终结果为3


int lengthOfLongestSubstring(char *s) {// 使用一个数组来存储每个字符最后出现的位置int charIndex[128];  // 假设字符集为ASCII,有128个字符memset(charIndex, -1, sizeof(charIndex));  // 初始化为-1int left = 0;  // 左指针,用于标记窗口的开始位置int maxLen = 0;  // 最长子串的长度int len = strlen(s);for (int right = 0; right < len; right++) {// 如果字符已经在窗口中,并且其位置在左指针之后if (charIndex[s[right]] >= left) {// 移动左指针到重复字符的下一个位置left = charIndex[s[right]] + 1;}// 更新每个字符的位置,每个字符初始left都是0charIndex[s[right]] = right;// 计算当前窗口的长度.正常是位置,如果该字符已经出现过了,就会更新left,减去的就是上一次出现的位置。int windowLen = right - left + 1;// 更新最长子串的长度if (windowLen > maxLen) {maxLen = windowLen;}}return maxLen;
}
  • right指针逐个增加,尝试扩大窗口。
  • 检查新加入的字符s[right]是否已经在当前窗口中。
  • 如果已经在窗口中并且其位置在left指针之后,更新left指针的位置。
  • 更新charIndex数组中s[right]字符的位置为right
  • 计算当前窗口的长度windowLen,并与maxLen比较,更新最长子串的长度。


http://www.ppmy.cn/ops/12466.html

相关文章

用html写一个旋转菜单

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>旋转菜单</title><link relstylesheet href"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css"&…

操作系统—系统调用(实验)

文章目录 系统调用1.实验目标2.实验过程记录(1).理解系统调用接口(2).阅读argraw、argint、argaddr和argstr(3).理解系统调用的解耦合实现方式(4).wait系统调用的非阻塞选项实现(5).yield系统调用的实现 3.存在的问题及解决方案实验小结 系统调用 1.实验目标 阅读并了解xv6内核…

Python 正则表达式

Python 正则表达式 目录 正则 flags:标志位 match函数 search函数 findall函数 finditer函数 元字符 匹配单个字符和数字 锚字符&#xff08;边界字符&#xff09; ^ 行首匹配 $ 行尾匹配 \A匹配字符串开始 \Z 匹配字符串结束 \b 匹配一个单词的边界 \B 匹配非单…

星途为什么对标奥迪

文/夏宁 在四月中旬举行的星途星纪元ET发布会上&#xff0c;星途致敬奥迪。会后&#xff0c;针对这一问题及有关产品热点&#xff0c;奇瑞集团星途品牌接受了媒体采访。接受采访的领导名单如下&#xff1a; 奇瑞汽车股份有限公司执行副总经理、奇瑞汽车工程技术研发总院 院长C…

【论文精读】DiffAttack:难以察觉和可转移的对抗性攻击的扩散模型

文章目录 一、文章概览&#xff08;一&#xff09;研究动机&#xff08;二&#xff09;扩散模型&#xff08;三&#xff09;文章工作 二、模型方法&#xff08;一&#xff09;问题表述&#xff08;二&#xff09;核心思想&#xff08;三&#xff09;具体框架1、DDIM反演技术2、…

unity 录制360全景渲染图

1.打开pakcageManager &#xff0c;选择packages为 unityRegisty&#xff0c;找到unityRecorder插件下载&#xff0c;点击右下角instant安装&#xff0c;如果插件列表为空&#xff0c;检查是否连接网络&#xff0c;重启Unity 2.打开录制面板 3.add recorder 选择ImageSequence …

上位机图像处理和嵌入式模块部署(树莓派4b与视觉slam十四讲)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 实际使用中&#xff0c;树莓派4b是非常好的一个基础平台。本身板子价格也不是很贵&#xff0c;建议大家多多使用。之前关于vslam&#xff0c;也就是…

基于Kepware的Hadoop大数据应用构建-提升数据价值利用效能

背景 Hadoop是一个由Apache基金会所开发的分布式系统基础架构&#xff0c;它允许用户在不需要深入了解分布式底层细节的情况下&#xff0c;开发分布式程序。Hadoop充分利用集群的威力进行高速运算和存储&#xff0c;特别适用于处理超大数据集。 Hadoop的生态系统非常丰富&…