1.题目解析
leedcode题目链接:https://leetcode.cn/problems/wtcaE1/
给定一个字符串 s ,请你找出其中不含有重复字符的 最长连续子字符串 的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子字符串是 "abc",所以其长度为 3。
示例 2:
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子字符串是 "b",所以其长度为 1。
示例 3:
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
示例 4:
输入: s = ""
输出: 0
2.算法原理
利用规律,使用“滑动窗口解决”。
1.先设两个指针:left = 0, right = 0
left
和right
中间管理的区域,就是窗口。
2.进窗口
让字符进入哈希表。
3.判断
如果窗口内出现重复字符,就出窗口,让left++
,从哈希表中删除该字符。然后在每次判断后,更新一下结果。
4.注意:
本题中,我们选择使用一个数组来模拟哈希表,原理是利用了字符的唯一性。每一个英文字符,都有一个唯一对应的ASCII码值。我们让这个ASCII码值作为哈希表的下标,来实现一一对应。比如,a
的ASCII码值是97
,那么对应哈希表中的元素就是hash[97]
。
然后,我们将模拟哈希表的数组都初始化为0
,表示表中目前没有一个字符(数组一定要足够大)。接着不断将字符放进表中,比如把a
放进去,我们就让哈希表中对应a
的位置+1
,表示a
有一个。又出现一个a
就再+1
,数组中97
位置的值,就对应当前窗口中字符a
的个数。
我们要用哈希表中对应位置的值,作为判断条件,一旦有位置的值大于1
了,就说命元素出现了重复,就需要进行出窗口的操作。
3.代码演示
class Solution {
public:
int lengthOfLongestSubstring(string s)
{
int right = 0, left = 0; // 定义两个指针
int n = s.size(); // 字符串大小
int hash[128] = {0}; // 用一个数组,模拟哈希表
int ret = 0; // 记录返回值
while(right < n)
{
hash[s[right]]++; // 计入哈希表,进窗口
while(hash[s[right]] > 1) // 说明发现了重复元素
{
hash[s[left]]--; // 出窗口
left++;
}
ret = max(ret, right - left + 1); // 更新数据
right++;
}
return ret;
}
};