Leetcode题目总结[3]无重复字符的最长字串

1.题目描述

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

 

示例 1:

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

示例 2:

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

示例 3:

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

示例 4:

输入: s = "" 输出: 0

 

提示:

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

2.做法

首先要分清楚子串和子序列

子串:串中任意个连续的字符组成的子序列称为该串的子串 如:coffee中的offe是一个子串

序列:序列是被排成一列的对象(或事件);这样每个元素不是在其他元素之前,就是在其他元素之后。这里,元素之间的顺序非常重要

子序列:子序列就是在原来序列中找出一部分组成的序列 如:coffee中的ofe可以是一个子序列,而不可以是一个子串

 

一开始啥想法都没有,瞄了一眼题解,滑动窗口+hashmap?

看了一会迷迷糊糊地也没怎么看懂 但是到自己真动手写的时候就知道为什么是滑动窗口+hashmap了

最暴力的做法就是枚举出所有区间并判断区间内是否有重复字符 并找出符合条件的最长区间

一共有Σ? 好吧算不出来总之就是很多个不合法区间

我们可以利用两个指针组成一个滑动窗口,从左往右移动窗口,每次右指针右移一位,加入一个字符,并判断现在的字串里有没有与新字符相同的字符,如果有,则加入这个新字符以后的子串不合法。

我们可以记录一下没加入新字符时的字串长度,

然后将左指针右移继续计算下面的字串

当所有的可能的合法区间都枚举并计算一遍后即可得到答案

 

判断:这里我是直接循环区间挨个字符判断,不知道有没有其他做法 比如利用hash表中存的字符出现的最后位置与指针位置比较直接判断之类的?(临时想法也没有试过也许有点得不偿失?)

左指针右移:一开始我以为只是单纯右移一位就可以了(只考虑了样例1的情况),但是右移之后遇到同样的字符会出问题(卡了样例3) 记录完pw子串的长度后 这个p就没有用了 因为以这个p开头的子串最长只能到这里,所以我们可以在记录完子串长度后就将这个p废弃掉, pw中的w也是,假如你说两个重复w直接可能还有其它合法字符,但是在遇到第二个w之后,以第一个w开头的子串最长也就到第二个子串为止,而以第一个w后面的字符开头的子串可能还会更长,所以我们可以舍弃掉第一个w,可以直接将左指针跳到第一个w+1的位置。于是我们用hash记录每个字符对应的最后出现的位置,在左指针右移时直接移动到对应位置+1就可以了。c++我用的不熟,就用数组暂时代替了

3.代码

C++:

1 /* 2 * @lc app=leetcode.cn id=3 lang=cpp 3 * 4 * [3] 无重复字符的最长子串 5 */ 6 7 // @lc code=start 8 class Solution { 9 public: 10 int lengthOfLongestSubstring(string s) { 11 int len = s.length(); 12 int maxans = 0; 13 int start = 0,flag = 0; 14 int temp; 15 int a[500]= {}; 16 if(len == 0) return 0; 17 for(int i = 0; i < len; i++) 18 { 19 20 for(int j = start; j < i; j++) 21 { 22 if(s[j] == s[i]) 23 { 24 flag = 1; 25 temp = a[s[i] - ' '] + 1; 26 break; 27 } 28 } 29 if(flag == 1) 30 { 31 start = temp; 32 } 33 maxans = max(maxans,i - start + 1); 34 flag = 0; 35 a[s[i] - ' '] = i; 36 } 37 return maxans; 38 } 39 }; 40 // @lc code=end

4.做题时遇到的错误

 runtime error: index -65 out of bounds for type ‘int [26]’ 

错误原因是数组越界

因为题目没有限制字符一定是26个英文字母,也可能有'-' ' ' '?' '!' '*'等符号

在建立hash表的时候要将表的范围扩大一点

我将表的范围扩到了500就可以了 (随便选的数字)


__EOF__

本文作者cheng_zhi
本文链接https://www.cnblogs.com/chengzhid/p/15214345.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   cheng_zhi  阅读(72)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示