给定一个字符串 s ,请你找出其中不含有重复字符的 最长
子串
的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: s = "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是"wke",所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke"是一个子序列,不是子串。
提示:
0 <= s.length <= 5 * 104s由英文字母、数字、符号和空格组成
因为s由英文字母、数字、符号和空格组成,符合ASCII码,故采用ASCII码大小的数组,使用ASCII码为下标,记录每个字符出现的最后位置。并在每次循环的开始,将left更新为上一次该字符出现的位置+1。
滑动窗口算法的基本原理:
-
初始化窗口:定义两个指针,通常是
left和right,并初始化为字符串或数组的起始位置。 -
滑动窗口:
right指针逐个增加,尝试扩大窗口,同时更新解的答案。 -
更新解的答案:当满足题目条件时,我们需要更新当前的最优解。
-
收缩窗口:如果当前窗口不满足题目的条件,移动
left指针缩小窗口,直到满足条件为止。
示例分析:
以题目"abcabcbb"为例,详细步骤如下:
-
初始化:
left = 0, right = 0, maxLen = 0, charIndex[] = {-1, -1, -1, ...} -
right逐个增加:s[0] = 'a',charIndex['a'] = -1,更新为charIndex['a'] = 0,窗口长度为1,maxLen = 1。s[1] = 'b',charIndex['b'] = -1,更新为charIndex['b'] = 1,窗口长度为2,maxLen = 2。s[2] = 'c',charIndex['c'] = -1,更新为charIndex['c'] = 2,窗口长度为3,maxLen = 3。s[3] = 'a',charIndex['a'] = 0,左指针移动到1,窗口变为"bca",窗口长度为3,maxLen保持不变。s[4] = 'b',charIndex['b'] = 1,左指针移动到2,窗口变为"cab",窗口长度为3,maxLen保持不变。s[5] = 'c',charIndex['c'] = 2,左指针移动到3,窗口变为"abc",窗口长度为3,maxLen保持不变。s[6] = 'b',charIndex['b'] = 1,左指针移动到4,窗口变为"bca",窗口长度为3,maxLen保持不变。s[7] = 'b',charIndex['b'] = 1,左指针移动到5,窗口变为"cab",窗口长度为3,maxLen保持不变。
最终结果为3。
int lengthOfLongestSubstring(char *s) {
// 使用一个数组来存储每个字符最后出现的位置
int charIndex[128]; // 假设字符集为ASCII,有128个字符
memset(charIndex, -1, sizeof(charIndex)); // 初始化为-1
int left = 0; // 左指针,用于标记窗口的开始位置
int maxLen = 0; // 最长子串的长度
int len = strlen(s);
for (int right = 0; right < len; right++) {
// 如果字符已经在窗口中,并且其位置在左指针之后
if (charIndex[s[right]] >= left) {
// 移动左指针到重复字符的下一个位置
left = charIndex[s[right]] + 1;
}
// 更新每个字符的位置,每个字符初始left都是0
charIndex[s[right]] = right;
// 计算当前窗口的长度.正常是位置,如果该字符已经出现过了,就会更新left,减去的就是上一次出现的位置。
int windowLen = right - left + 1;
// 更新最长子串的长度
if (windowLen > maxLen) {
maxLen = windowLen;
}
}
return maxLen;
}
right指针逐个增加,尝试扩大窗口。- 检查新加入的字符
s[right]是否已经在当前窗口中。 - 如果已经在窗口中并且其位置在
left指针之后,更新left指针的位置。 - 更新
charIndex数组中s[right]字符的位置为right。 - 计算当前窗口的长度
windowLen,并与maxLen比较,更新最长子串的长度。









![OpenHarmony移植的加解密库—libsodium [GN编译]](https://img-blog.csdnimg.cn/img_convert/48b1e7eff01309fe163e3e6dcf6fba55.webp?x-oss-process=image/format,png)









