int lengthOfLongestSubstring(char *s){
int hash[128] = { 0 };
int length = strlen(s);
int maxLen = 0;
int curr = 0;
if (length <= 1) return length;
for (int ii=0; ii<length; ii++) {
for (int i=ii; i<length; i++) {
int index = s[i] % 128;
if (hash[index] == 0) {
curr += 1;
} else {
break;
}
hash[index] = 1;
}
for (int j=0; j<128; j++) {
hash[j] = 0;
}
maxLen = maxLen > curr ? maxLen : curr;
if (maxLen == 128) break;
curr = 0;
}
return maxLen;
}
解题思路:
字符在C语言中使用ASCII编码,创建一个哈希表,大小为128,字符值作为索引,值默认为0.
从第一个字符开始遍历输入字符串,依次将字符存入哈希表中,存之前先判断表中的值是否为0,为0说明之前没有存过,为1说明这个字符已经出现过了。结束这次遍历,再从第二个字符开始遍历字符串。
需要两个for循环,算法复杂度为n^2,耗时较久。
看了看别人的代码
int lengthOfLongestSubstring(char * s){
char *cur = s, *head = s;
int max = 0;
while (*cur) {
for (char *p = head; p < cur; ++p)
if (*p == *cur) {
head = p + 1;
break;
}
max = cur - head + 1 > max ? cur - head + 1 : max;
++cur;
}
return max;
}
想象有两个指针,一开始都指向字符串开头,一个在上面滑动(curr),一个在下面滑动(head),指针p在head和curr之间滑动,用来判断head与curr之间没有重复字符。如果p找到了重复字符(与curr所指向的字符相同),那么head移动到p所指向的后一个字符,如果没有找到重复字符,curr向后移动一个字符。
asdfabcd
先找到 asdf,此时子串长度为4,max=4
再找到 sdfabc,此时子串长度为6,max=6
再找到 fabcd,此时子串长度为5,max=6
动态规划与分治
学到了:
对于字符串的遍历,不一定要用for循环,不需要先计算长度,字符串结尾是\0,使用while循环直接遍历即可。