滑动窗口
- 创建两个指针 start 和 end,分别指向窗口起止位置。对于长度为 n 的字符串,总共需要循环 n 次。
- 每次循环时,end 指针加一,同时保存当前字符的下一个位置,然后判断是否出现重复字符。
- 如果无重复,则继续下次循环
- 如果重复,则把 start 移到记录中对应字符的下一个位置
#include <stdio.h>
#include <string.h>
int lengthOfLongestSubstring(char * s){
int index[128] = {0};
int start, end;
int max = 0, len;
for (start = 0, end = 0; end < strlen(s); end++) {
start = start < index[s[end]] ? index[s[end]] : start;
len = end - start + 1;
max = max < len ? len : max;
index[s[end]] = end + 1;
}
return max;
}
int main(void) {
printf("%d\n", lengthOfLongestSubstring("abadc"));
return 0;
}
暴力破解
字符串有 n 个字符,对于第一个字符,可能的字符串有 n - 1 个。对于每个字符串都要判断一次是否有重复字符,最大 n - 1 次。暴力破解的时间复杂度是 O(n^3)。
每次判断是否有重复字符时,可以借助哈希表,此时时间复杂度是 O(n^2)。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define HASHTABLESIZE 128
typedef struct HashTableStruct {
char data[HASHTABLESIZE];
int size;
} *HashTable;
int hash(char key, int size) {
return key;
}
int insert(HashTable ht, char key) {
int h = hash(key, ht->size);
if (ht->data[h] == 0) {
ht->data[h] = key;
return 0;
}
return -1;
}
int lengthOfLongestSubstring(char * s){
int max = 0, max_total = 0;
int len;
int i, j;
int ret;
HashTable ht = malloc(sizeof(struct HashTableStruct));
memset(ht->data, 0, HASHTABLESIZE);
ht->size = HASHTABLESIZE;
if (strlen(s) < 2) return strlen(s);
for (i = 0; i < strlen(s) - 1; i++) {
for (j = i; j < strlen(s); j++) {
ret = insert(ht, s[j]);
if (ret == -1) {
len = j - i;
max = max < len ? len : max;
break;
}
max++;
}
max_total = max_total < max ? max : max_total;
max = 0;
memset(ht->data, 0, HASHTABLESIZE);
}
return max_total;
}
int main(void) {
int ret = lengthOfLongestSubstring("abcdd");
printf("%d\n", ret);
return 0;
}