题目链接:LCR 016. 无重复字符的最长子串 - 力扣(LeetCode)
题目:
输入一个字符串,求该字符串中不含重复字符的最长子字符串的长度。例如,输入字符串 "babcca",其最长的不含重复字符的子字符串是 "abc",长度为 3。
分析:
和前面的题目一样,此处还是用一个哈希表统计子字符串中字符出现的次数。如果一个子字符串中不含重复的字符,那么每个字符都只出现一次,它们在哈希表中对应的值为 1。没有在子字符串中出现的其他字符对应的值都是 0。也就是说,如果子字符串中不含重复字符,那么它对应的哈希表中没有比 1 大的值。
下面仍然用两个指针来定位一个子字符串,其中第 1 个指针指向子字符串的第 1 个字符,第 2 个指针指向子字符串的最后一个字符。接下来分析如何移动这两个指针。
如果两个指针之间的子字符串不含重复的字符,由于目标是找出最长的子字符串,因此可以向右移动第 2 个指针,在子字符串的最右边增加新的字符,然后判断新的字符在子字符串中有没有重复出现。如果还是没有重复的字符,则继续向右移动第 2 个指针,在子字符串中添加新的字符。
如果两个指针之间的子字符串中含重复的字符,则可以向右移动第 1 个指针,删除子字符串中最左边的字符。如果删除最左边的字符之后仍然包含重复的字符,则继续向右移动第 1 个指针删除最左边的字符。如果删除最左边的字符之后不再包含重复的字符,就可以向右移动第 2 个指针,在子字符串的最右边添加新的字符。
代码实现:
class Solution {
public:
? ?int lengthOfLongestSubstring(string s) {
? ? ? ?int n = s.size(); ? ? ? ?
? ? ? ?vector<int> counts(128, 0);
? ? ? ?int longest = 0;
? ? ? ?int left = 0;
? ? ? ?for (int right = 0; right < n; ++right)
? ? ? {
? ? ? ? ? ?++counts[s[right]];
? ? ? ? ? ?while (counts[s[right]] == 2)
? ? ? ? ? {
? ? ? ? ? ? ? ?--counts[s[left]];
? ? ? ? ? ? ? ?++left;
? ? ? ? ? }
? ? ? ? ? ?if (right - left + 1 > longest)
? ? ? ? ? ? ? ?longest = right - left + 1; ? ? ?
? ? ? }
? ? ? ?return longest;
? }
};
由于这个题目没有说明字符串中只包含英文字母,那么就有可能包含数字或其他字符,因此字符就可能不止 26 个。假设字符串中只包含 ASCII 码的字符,由于 ASCII 码总共有 128 个字符,因此用来模拟哈希表的数组的长度就是 128。