重复字符的最长子串
给定1个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
解题思路:
创建一个数组,并初始化为0,数组一共有256个元素,数组下标代表字符的ASCII码。从头遍历字符串,当出现某个字符,就在该字符下标所在的数组元素记录该字符在字符串的偏移位置(相对起始位置)。遍历某个字符串字符发现该字符下标数组元素值为0,则代表该字符未出现过,并用left表示当前寻找最长子串的所在字符串起始位置(并不代表最长子串所在的字符串起始位置)。当遍历某个字符串字符发现该字符下标数组元素值为0时或小于left值时,无重复字符的长度为max(已经保存的最长长度值,当前遍历字符的偏移值-left+1).
1 #include<string>
2 #include<iostream>
3 using namespace std;
4 int lengthOfLongestSubstring(string s)
5 {
6 int m[256] = {0}, res = 0, left = 0;
7 for (int i = 0; i < s.size(); ++i)
8 {
9 if (m[s[i]] == 0 || m[s[i]] < left)
10 {
11 res = max(res, i - left + 1);
12 }
13 else
14 {
15 left = m[s[i]];
16 }
17 m[s[i]] = i + 1;
18 }
19 return res;
20 }
21 int main()
22 {
23 string mystring;
24 while(1)
25 {
26 cin>>mystring;
27 if(mystring.compare("exit")==0)
28 {
29 break;
30 }
31 cout<<"最长无重复字符长度:"<<lengthOfLongestSubstring(mystring)<<endl;
32 }
33 return 0;
34 }
程序中那个if条件语句中为啥要有个m[s[i]] < left,我们用一个例子来说明,当输入字符串为"abbca"的时候,当i=4时,也就是即将要开始遍历最后一个字母a时,此时数组中a字符下标所在的元素值对应1,b对应3,c对应4,left为2,即当前最长的子字符串的左边界为第二个b的位置,而第一个a已经不在当前最长的字符串的范围内了,那么对于i=4这个新进来的a,应该要加入结果中,而此时未被更新的哈希表中a为1,不是0,如果不判断它和left的关系的话,就无法更新结果,那么答案就会少一位,所以需要加m[s[i]] < left。