无重复字符的最长字串
文章目录
- 无重复字符的最长字串
- 题目描述
- 算法思路
- 思路一
- 思路二
- 代码编写
- 暴力解法
- 滑动窗口
3. 无重复字符的最长子串 - 力扣(LeetCode)
题目描述
给定一个字符串 s
,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
提示:
0 <= s.length <= 5 * 104
s
由英文字母、数字、符号和空格组成
算法思路
思路一
暴力枚举+哈希(判断字符是否重复出现)
O(n^2)
枚举「从每⼀个位置」开始往后,⽆重复字符的⼦串可以到达什么位置。找出其中⻓度最⼤的即可。
在往后寻找⽆重复⼦串能到达的位置时,可以利⽤「哈希表」统计出字符出现的频次,来判断什么时候⼦串出现了重复元素。
思路二
滑动窗口(窗口内所有的元素都是不重复的)
滑动窗口一般思路都是,进窗口,判断条件(出窗口),更新结果
做法:右端元素right
进入窗口的时候,哈希表统计这个字符的频次:
- 如果这个字符出现的频次超过1,说明窗口内有重复元素,那么就从左侧开始划出窗口,直到c这个元素的频次变为1,然后再更新结果。
- 如果没有超过1,说明当前窗口没有重复元素,可以直接更新结果
代码编写
暴力解法
// 暴力解法 枚举+哈希
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int ret = 0; // 结果
int n = s.size();
// 枚举
for(int i = 0; i < n ; i ++)
{
int hash[128] = {0};
for(int j = i ; j < n;j ++)
{
hash[s[j]]++;
if(hash[s[j]] > 1) break;
ret = max(ret, j + 1 - i);
}
}
return ret;
}
};
滑动窗口
// 优化:滑动窗口 数组模拟哈希
class Solution {
public:
int lengthOfLongestSubstring(string s) {
// 用数组模拟哈希 一般 128 就够用了
int hash[128] = {0};
int left = 0, right = 0;// 定义左右端点
int n = s.size(), ret = 0;
while(right < n)
{
// 进入窗口
hash[s[right]]++;
// 判断
while(hash[s[right]] > 1)
// 出窗口
hash[s[left++]]--;
// 更新结果
ret = max(ret, right - left + 1);
// 下一个元素
right++;
}
return ret;
}
};
威力还是不错的~