一、题目
对于一个字符串,请设计一个高效算法,找到字符串的最长无重复字符的子串长度。
给定一个字符串A及它的长度n,请返回它的最长无重复字符子串长度。保证A中字符全部为小写英文字符,且长度小于等于500。
测试样例:
“aabcb”,5
返回:3
二、解题思路
- 设立一个hash表记录每个字母前一次出现的坐标;
- 设立一个pre数组记录字符串到该字母为止,包含该字母可以取得的最大不重复字符串。
例:
标号i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
字母A[i] | a | c | a | b | d | e | b | c |
- i=0: a新出现,位置为0,包含此a的最大不重复字母子串为a,长度为1;
- i=1: c新出现,位置为1,包含此c的最大不重复字母子串为ac,长度为2;
- i=2: a已经出现过了,要获得包含此a的串必须考虑包含前一位(c)的最大字符串是否包含前一个a;ac包含前一个a,所以最大不重复字母子串为ca,长度为2,更新a的位置为2;
- i=3: b新出现,位置为3,包含此b的最大不重复字母子串为cab,长度为3;
- i=4: d新出现,位置为4,包含此d的最大不重复字母子串为cabd,长度为4;
- i=5: e新出现,位置为5,包含此e的最大不重复字母子串为cabde,长度为5;
- i=6: b已经出现过了,要获得包含此b的串必须考虑包含前一位(e)的最大字符串是否包含前一个b;cabde包含前一个b,所以最大不重复字母子串为edb,长度为3,更新b的位置为6;
- i=7: c已经出现过了,要获得包含此c的串必须考虑包含前一位(b)的最大字符串是否包含前一个c;edb不包含前一个c,所以最大不重复字母子串为edbc,长度为4,更新c的位置为7;
因此比较生成的最大不重复字母子串 a ac ca cab cabd cabde edb edbc 最大的子串为cabde 长度为5.
三、代码实现
class DistinctSubstring {
public:
int longestSubstring(string A, int n) {
int hash[26];//26个字母
memset(hash, -1, sizeof(hash));//所有字母hash表值初始为-1
int *pre = new int[n];//动态数组
int maxlengthsbustring = 0;
pre[0] = 1;
hash[A[0] - 'a'] = 0; //第一个字母的hash表值为它的位置0
for (int i = 1; i < n; i++){
if (hash[A[i] - 'a'] == -1){//新字母
pre[i] = pre[i - 1] + 1;
}
else{//前面已有的字母x
if (hash[A[i] - 'a'] >= i - pre[i - 1]){//相同字母存在于前一个pre串中
pre[i] = i - hash[A[i] - 'a'];
}
else{
pre[i] = pre[i - 1] + 1;
}
}
hash[A[i] - 'a'] = i;
if (pre[i] > maxlengthsbustring)
maxlengthsbustring = pre[i];
}
delete pre;
return maxlengthsbustring;
}
};