给定一个字符串
s,请你找出其中不含有重复字符的 最长 子串 的长度。示例 1:
输入: s = "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是"abc",所以其长度为 3。示例 2:
输入: s = "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是"b",所以其长度为 1。示例 3:
输入: s = "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是"wke",所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke"是一个子序列,不是子串int lengthOfLongestSubstring(char* s) { if (s == NULL || *s == '\0') return 0; int n = strlen(s); if (n == 1) return 1; int charIndex[128]; // 哈希表:记录字符最近出现的位置 memset(charIndex, -1, sizeof(charIndex)); int maxLength = 0; // 记录最大长度 int left = 0; // 滑动窗口左边界 for (int right = 0; right < n; right++) { char currentChar = s[right]; // 关键步骤1:检查重复字符 if (charIndex[currentChar] >= left) { left = charIndex[currentChar] + 1; } // 关键步骤2:更新字符位置 charIndex[currentChar] = right; // 关键步骤3:更新最大长度 int currentLength = right - left + 1; if (currentLength > maxLength) { maxLength = currentLength; } } return maxLength; }
分步详细解析
步骤1:初始化阶段
int charIndex[128]; // 创建哈希表(128个ASCII字符)
memset(charIndex, -1, sizeof(charIndex)); // 全部初始化为-1
int maxLength = 0; // 最大长度初始为0
int left = 0; // 窗口左边界从0开始
解释:
-
charIndex数组就是我们的哈希表 -
数组下标对应字符的ASCII码,值记录该字符最近出现的位置
-
初始化为-1表示所有字符都还没出现过
-
left是滑动窗口的左边界,right是右边界
步骤2:遍历字符串(右指针移动)
for (int right = 0; right < n; right++) {
char currentChar = s[right]; // 当前字符
// ... 后续处理
}
解释:
-
right指针从0开始,逐个字符向右移动 -
每次循环处理一个字符,扩展窗口的右边界
步骤3:检查重复字符(核心逻辑)
if (charIndex[currentChar] >= left) {
left = charIndex[currentChar] + 1;
}
详细分析:
情况1:字符第一次出现
-
charIndex[currentChar] == -1(初始值) -
-1 >= left为 false -
不进入if语句,左边界
left保持不变
情况2:字符在窗口外出现过
-
比如:
"abcade",当处理第二个'a'时 -
第一个'a'在位置0,但当前
left可能在位置3 -
charIndex['a'] = 0,0 >= 3为 false -
不进入if语句,这个'a'不算重复(因为不在当前窗口内)
情况3:字符在窗口内重复
-
比如:
"abcabc",当处理第二个'b'时 -
第一个'b'在位置1,当前
left在位置0 -
charIndex['b'] = 1,1 >= 0为 true -
进入if语句:
left = 1 + 1 = 2 -
窗口左边界跳到重复字符的下一个位置
步骤4:更新字符位置
charIndex[currentChar] = right;
解释:
-
无论是否重复,都要更新该字符的最新位置
-
哈希表始终记录每个字符最后一次出现的位置
-
为下一次检查重复做准备
步骤5:计算当前窗口长度
int currentLength = right - left + 1;
if (currentLength > maxLength) {
maxLength = currentLength;
}
解释:
-
right - left + 1计算当前无重复子串的长度 -
如果比之前记录的最大值大,就更新
maxLength
具体示例演示
示例:s = "abcabcbb"
步骤0: 初始化
charIndex: 全部为-1, left=0, maxLength=0步骤1: right=0, char='a'
检查: charIndex['a']=-1 >=0? false → left不变=0
更新: charIndex['a']=0
长度: 0-0+1=1, maxLength=1步骤2: right=1, char='b'
检查: charIndex['b']=-1 >=0? false → left=0
更新: charIndex['b']=1
长度: 1-0+1=2, maxLength=2步骤3: right=2, char='c'
检查: charIndex['c']=-1 >=0? false → left=0
更新: charIndex['c']=2
长度: 2-0+1=3, maxLength=3步骤4: right=3, char='a' ← 出现重复!
检查: charIndex['a']=0 >=0? true → left=0+1=1
更新: charIndex['a']=3
长度: 3-1+1=3, maxLength=3步骤5: right=4, char='b' ← 出现重复!
检查: charIndex['b']=1 >=1? true → left=1+1=2
更新: charIndex['b']=4
长度: 4-2+1=3, maxLength=3步骤6: right=5, char='c' ← 出现重复!
检查: charIndex['c']=2 >=2? true → left=2+1=3
更新: charIndex['c']=5
长度: 5-3+1=3, maxLength=3步骤7: right=6, char='b' ← 出现重复!
检查: charIndex['b']=4 >=3? true → left=4+1=5
更新: charIndex['b']=6
长度: 6-5+1=2, maxLength=3步骤8: right=7, char='b' ← 出现重复!
检查: charIndex['b']=6 >=5? true → left=6+1=7
更新: charIndex['b']=7
长度: 7-7+1=1, maxLength=3

2134

被折叠的 条评论
为什么被折叠?



