给定一个字符串 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;}
};