闲来无事刷了一下leetcode,本以为是很水的题目,却在第三题卡了很久没ac;为此,特地写下此博文,算是和初学者一同分享此题的易错点吧。
题目:Given a string, find the length of the longest substring without repeating characters.
Examples:
Given “abcabcbb”, the answer is “abc”, which the length is 3.
Given “bbbbb”, the answer is “b”, with the length of 1.
Given “pwwkew”, the answer is “wke”, with the length of 3. Note that the answer must be a substring, “pwke” is a subsequence and not a substring.
题目意思很简单,就是求一个字符串的最长连续无重复的子序列的长度。乍一看,很简单,一个dp就解决了,于是兴高采烈的写完了代码,结果一交,超时了。然后我便一直卡在这个标签为“medium”的题目里面。直到今天早上突然觉醒,(果然自己很菜),用哈希不就完了吗,把每个字母出现的位置用一个数组存起来,每次维护一个maxlen, 这样只需遍历一遍数组就可以求出答案。 代码如下:
#include <stdio.h>
#define max(a, b) (a > b ? a : b)
int main(){
freopen("a.in", "r", stdin);
freopen("a.out", "w", stdout);
int w[500], st = 0, ed = 0, maxlen = 0, i, j;
char s[500]; scanf("%s", s);
for (i = 0; i < 300; i ++) w[i] = -1;
while (s[ed] != NULL){
if (w[s[ed]] != -1){
for (j = st; j < w[s[ed]]; j ++) w[s[j]] = -1;
st = w[s[ed]] + 1;
w[s[ed]] = ed ++;
}
else {
maxlen = max(maxlen, ed - st + 1);
w[s[ed]] = ed ++;
}
}
printf("%d", maxlen);
return 0;
}
至于复杂度为什么是O(n)的,是因为只遍历了一遍数组,且系数至多为2(此处为个人理解)。