思路:
1)使用滑动窗口的方法解题;
2)使用哈希集合来存储窗口 \[i, j)(最初 j = i)中的字符,同时检查下一个字符是否可以添加到窗口中,如果可以则添加到窗口中并更新答案,否则窗口向右滑动。
3)使用数组来模拟哈希集合的功能。
代码如下:
#include <string.h>
int lengthOfLongestSubstring(char * s){
// 初始化窗口的左右边界以及最大子串长度
int left = 0, right = 0, maxLen = 0;
// 用来存储字符出现状态的数组,索引对应字符的ASCII码,值为布尔类型,表示该字符是否出现过
int charTable[128] = {0};
// 获取字符串长度
int sLen = strlen(s);
// 循环条件是右边界小于字符串长度
while(right < sLen){
// 如果当前字符未出现过
if(charTable[s[right]] == 0){
// 标记字符出现
charTable[s[right]] = 1;
// 将当前子串长度与最大子串长度进行比较,取大者
maxLen = maxLen > right - left + 1 ? maxLen : right - left + 1;
// 右边界向右移动
right++;
}else{
// 如果当前字符出现过,那么左边界需要向右移动,直到移动到重复字符的位置
// 同时需要将移动过程中的字符标记为未出现
charTable[s[left]] = 0;
left++;
}
}
// 返回最大子串长度
return maxLen;
}
在C语言中,一个`int`类型的数组可以被初始化为全0。对于ASCII码的范围是0~127(共128个字符),可以使用一个长度为128的数组来表示每个字符的出现状态。数组的索引对应字符的ASCII码,值为布尔类型,表示该字符是否出现过。
在代码中,`charTable`数组被声明为`int charTable[128]`,并使用初始化列表 `{0}` 将所有元素初始化为0。这意味着所有的ASCII码对应的字符初始状态都未出现过。
例如,字符 'a' 的ASCII码是97,那么 `charTable[97]` 表示字符 'a' 的出现状态.
如果 `charTable[97]` 的值为1,表示字符 'a' 已经出现过;如果值为0,表示字符 'a' 还未出现过。
在算法的执行过程中,可以通过 `charTable[s[right]]` 来获取字符 `s[right]` 的出现状态,并根据这个状态进行相应的处理。
补充说明:
定义一个`int`类型的数组 `n` ,通过 `n[a]` 可以获取字符 `a` 的ASCII码对应的数组元素。
#include <stdio.h>
int main() {
int n[128] = {0}; // 初始化数组,所有元素都为0
char c = 'a';
int ascii = (int)c; // 获取字符 'a' 的ASCII码
n[ascii] = 1; // 将字符 'a' 的出现状态标记为1
printf("ASCII of 'a': %d\n", ascii);
printf("Value at n[97]: %d\n", n[ascii]); // 输出:Value at n[97]: 1
return 0;
}
在上述示例中,定义了一个大小为128的整型数组 `n`,并将所有元素初始化为0。
然后获取字符 `'a'` 的ASCII码,并将对应的数组元素 `n[97]` 的值设置为1。通过 `n[97]` 就可以获取字符 `'a'` 的出现状态。
注:数组 `n` 的索引应该在有效的ASCII码范围内,即0~127。如果字符的ASCII码超出了这个范围,访问对应的数组元素可能会导致越界错误。