题目来源:
力扣(LeetCode)
题目描述 📑
给定一个字符串 s
,请你找出其中不含有重复字符的 最长子串 的长度。
示例 📝
示例1:
**输入:** s = "abcabcbb"
**输出:** 3
**解释:** 因为无重复字符的最长子串是 `"abc",所以其`长度为 3。
示例2:
**输入:** s = "bbbbb"
**输出:** 1
**解释:** 因为无重复字符的最长子串是 `"b"`,所以其长度为 1。
示例3:
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/longest-substring-without-repeating-characters
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
提示:
0 <= s.length <= 5 * 104
s
由英文字母、数字、符号和空格组成
解题思路 🤔
思路一 滑动窗口
首先审题,我们需要找出一个子串,最长且无重复,
让我们先从头开始,假设这个子串在字符串s中的index为head和tail,最开始 这两个index的值都为0,即head=tail=0;
- tail开始递增遍历字符串,遍历的过程中,head和tail标识的子串不停的变长的,此时能不停获取到不同的子串.
- 在tail递增的过程中,我们需要保证子串中没有重复对的字符,为了保证这点,我们需要对tail递增时新增的字符进行检查,检查head和tail代表的的子串中是否有该字符,有则移动head到子串中的字符index+1
- 上述操作中我们会获得所有的无重复字符的子串,只要记录下最大长度,也就OK了
💡OK! 伪代码如下:
class Solution {
public:
int lengthOfLongestSubstring(string s) {
if(s.size() is 0 or 1)
return size;
}
int head =0, tail = 0;
int max_len=1;
for(int i=0;i<s.size()){
tail++;
查看子串是否含有 s[tail];
if(含有){
head=该字符在子串中index+1;
}
max_len= max{max_len,tail-head};
}
return max_len;
};
再进一步,做点优化:
当记录的最大长度已经大于s的长度减去head时,说明不会有更长的子串了,此时 直接返回max_len就可以了
伪代码如下:
class Solution {
public:
int lengthOfLongestSubstring(string s) {
if(s.size() is 0 or 1)
return s.size();
}
int head =0, tail = 0;
int max_len=1;
for(int i=0;i<s.size();++i){
tail++;
查看子串是否含有 s[tail];
if(含有){
head=该字符在子串中index+1;
if(max_len>=s.size()-head){
return max_len;
}
}
max_len= max{max_len,tail-head};
}
return max_len;
};
最多只做一个遍历
时间复杂度为:O(n)
思路一 Code
class Solution {
public:
int lengthOfLongestSubstring(string s) {
size_t size=s.size();
if(0==size||1==size){
return size;
}
size_t head = 0;
int max_len=0;
int cur_len=0;
int tmp_index=0;
std::map<char,size_t> sub_str;
for(size_t tail = 0;tail<size;tail++){
if(sub_str.find(s[tail])!=sub_str.end()){
tmp_index=sub_str[s[tail]];
if(tmp_index>=head){
//当找到的字符的index在[head,tail)范围内才是重复的
head=tmp_index+1;
if(max_len>=size-head){
return max_len;
}
}
}
sub_str[s[tail]]=tail;
cur_len=tail-head+1;
max_len=max_len>cur_len?max_len:cur_len;
}
return max_len;
}
};
思路一 提交结果
提交3次结果如下
提交结果 | 执行用时 | 内存消耗 | 用时击败 | 内存击败 |
---|---|---|---|---|
通过 | 24 ms | 8.4 MB | 51.33% | 53.71% |
通过 | 16 ms | 8.3 MB | 70.72% | 54.68% |
通过 | 16 ms | 8.3 MB | 70.72% | 54.03% |