原题链接
思路一:
枚举每个开头, 用map容器统计以此字母开头的每个字母的个数,发现扫描到某个字母出现过了就得出以前面开头的字母的最长不含重复字符的串长度。
比如 abca 以 a开头,扫描序列,发现扫描到 第四个字母的时候是 a,a前面出现过了,得出当前最长的串的长度是3,即abc。然后以第二个字母b开头,发现最长的串是bca, 同样的做法,以第三个c开头,发现最长的串是ca …
时间复杂度是O(N*N) N是字符串的长度
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int length = s.length();
if(length == 0)
return 0;
int res = 0;
for(int i = 0; i < length; i++){//枚举每个开头
map<char, int>mp;
int curMax = 0;
mp[s[i]]++;//当前开头的字符出现次数加1
int j;
for(j = i + 1; j < length; j++){//枚举前面,看能否构成的最长的不含重复的串
if(mp[s[j]])//出现过了。最长的串是i到j-1这部分的串
break;
else
mp[s[j]]++;
}
curMax = j - i;
res = res > curMax ? res : curMax;//更新最长的
}
return res;
}
};
思路二:
**建立一个滑动窗口,滑动窗口的串是不含重复字符的串。**一开始设一指针指向最长的不含重复字符的串的开头,相当于窗口的左边, 设定另一个指针作为窗口的右边,活动右窗口指针,发现如果没有重复的话继续滑动窗口, 如果重复的话就把左窗口滑动到重复字符的下一个的字符上。
比如求 abcdbefg 这个最长不重复子串,左窗口指向0号位置, 右窗口指向0,移动右窗口,发现移动到4号位置,即b的时候和前面的1号位置的b重复了, 那么就把左窗口移动到1号的下一位,即c上。滑动窗口的时候同时更新最大长度。
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int length = s.length();
if(length == 0)
return 0;
int res = 0;
int * hash = new int[130];
//建立每个字符的出现的位置的映射。比如
//hash[122]=1.表示字符z出现的位置是1.
for(int i = 0; i < 130; i++){
hash[i] = -1;
}
int left = 0, right = 0;//左窗口和右窗口
while(left < length && right < length){
//如果字符没有出现过,或者字符在左窗口前面(相当于也是没有出现过)
if(hash[(int)s[right]] == -1 || hash[(int)s[right]] < left){
hash[(int)s[right]] = right;//记录这个字符出现的位置
res = max(res, right - left +1);//更新最大长度
right++;//窗口移动到下一位
}
else{//如果字符出现过了
//更新不重复的最长子串
res = res > (right - left) ? res : (right - left);
left = hash[(int)s[right]] + 1;//更新左窗口的位置(重复出现的字符的下一个位置)
hash[(int)s[right]] = right;//更新重复字符的位置
right++;
}
}
return res;
}
};
JAVA版本:
注意的地方,用s.charAt(index)获取在index处的字符。
package Leetcode;
public class Solution {
public static int lengthOfLongestSubstring(String s) {
int length = s.length();
if(length <= 0)
return 0;
int []hash = new int[123];
for(int i = 0; i < 123; i++) {
hash[i] = -1;
}
int left = 0, right = 0;
int res = 1;
while(left < length && right <length) {
if(hash[ (int)s.charAt(right) ] == -1 || hash[ (int)s.charAt(right) ] < left) {
res = Math.max(res, right - left +1);
hash[(int)s.charAt(right)] = right;
right++;
}
else {
res = Math.max(res, right - left);
left = hash[(int)s.charAt(right)] +1;
hash[(int)s.charAt(right)] = right;
right++;
}
}
return res;
}
public static void main(String args[]) {
String str = "qopubjguxhxdipfzwswybgfylqvjzhar";
int res = lengthOfLongestSubstring(str);
System.out.println(res);
}
}