无重复字符的最长子串
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
我的答案
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int largeLength = 0;//最大不重复子串长度
set<char> set_str;
for(int i = 0;i < s.length();++i)
{
for(int j = i;j < s.length();++j)
{
if(set_str.find(s[j]) != set_str.end())
{
set_str.clear();
break;
}
else
{
set_str.insert(s[j]);
largeLength = set_str.size() > largeLength ? set_str.size() :largeLength;
}
}
}
return largeLength;
}
};
讨论区优秀答案
class Solution {
public:
int lengthOfLongestSubstring(string s) {
vector<int> m(128,0);//这个容器为了存当遇到相同的字符(假设是a)时i应该变成的值,即前面那个a的下一个字符
int ans=0; //最终的子串长度
int i=0;
for(int j=0;j<s.size();j++){
i=max(i,m[s[j]]);//如果遇到了相同的字符(假设为a),此时m[s[j]]会又去到同样的存储单元m[a的ASCII码值],因为之前遇到a时已经将这个位置的值改成前面那个a的下一个位置了,所以m[s[j]]大于i,将i更新
m[s[j]]=j+1;//更新这个位置的值,当下次再遇到该字母时,将i调整到该字母下一个位置的地方
ans=max(ans,j-i+1);//更新最终结果值,即没相同字母的子串的字符个数
}
return ans;
}
};
答案原理 划窗算法
思路
滑动窗口,保证每个窗口里字母都是唯一的
2、使用 vector<int> m 来记录一个字母如果后面出现重复时,i 应该调整到的新位置 21. 所以每次更新的时候都会保存 j + 1 ,即字母后面的位置
3、j 表示子串的最后一个字母,计算子串长度为 j - i + 1