给定一个字符串 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
由英文字母、数字、符号和空格组成
题解
首先是我自己的思路,因为比较直接所以比较暴力
遍历字符串的每个字符,按照当前无重复字符的字串的长度提取子串,在字串中寻找是否有相同的字符,如果有相同的字符,更新子串的起始字符为相同字符的后面一个字符,同时更新当前字串的长度
这里寻找相同字符的位置比较讲究,首先找出相同字符在子串的位置,再加上字串在字符串中的位置,之所以用rfind倒着查找是避免存在多个相同字串返回第一个字串的结果,用rfind加上i的位置可以返回正确位置的子串的位置
class Solution {
public:
int lengthOfLongestSubstring(string s) {
if(s=="")
return 0;
int longest=1,begin=0,longer=1;
string son;
for(int i=1;i<s.size();i++){
son=s.substr(begin,longer);
int newBegin=son.find(s[i]);
if(newBegin!=string::npos){
newBegin=s.rfind(son,i-1)+newBegin;
longer=i-newBegin;
begin=newBegin+1;
}else{
longer++;
longest=longest<longer?longer:longest;
}
}
return longest;
}
};
下面这个是更加简洁和优化的写法,思路还是一样的
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int longest=0,begin=0,end=0;
while(end<s.size()){
for(int i=begin;i<end;i++){ //子串重复判断
if(s[i]==s[end]){
begin=i+1; //更新子串起始位置
break;
}
}
longest=max(longest,end-begin+1);
end++;
}
return longest;
}
};