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

1.题目描述

给定一个字符串 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 由英文字母、数字、符号和空格组成

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就可以了 (随便选的数字)

posted @ 2021-09-01 14:01  cheng_zhi  阅读(85)  评论(0)    收藏  举报