问题
LeetCode3:
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
思路
- 记录每一个元素上一次出现时的索引
- 关键在于
start
索引的更新- 以前一次出现时的下一个元素作为新子串的起始索引
解答
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
/* *
* 计算从字符串到start到end的长度
* */
int lengthOfLongestSubstring(string s) {
int* mark = (int*)malloc(sizeof(int) * 255);
memset(mark, -1, sizeof(int) * 255);
int start = 0;
int end = 0;
int maxLen = 0;
if (s.empty())
return 0;
for (int i = 0; i<s.length(); i++) {
if (mark[s[i]] == -1)
{
mark[s[i]] = i;
end = i;
}
else
{
if (mark[s[i]] < start){
mark[s[i]] = i;
end = i;
}
/*
* 更新起始位置,该元素上一次出现的位置为mark[s[i]]
* 从下一个位置开始计算新的子串长度
*/
else {
start = mark[s[i]] + 1;
mark[s[i]] = i;
end = i; //相同字符串之间元素的个数+1为当前长度
}
}
if (end - start + 1> maxLen)
{
maxLen = end - start + 1;
}
}
return maxLen;
}
int main()
{
string s;
getline(cin,s);
int len = lengthOfLongestSubstring(s);
cout<<"Len is "<<len<<endl;;
return 0;
}