题目:
自己的代码:
class Solution {
public int lengthOfLongestSubstring(String s) {
if(s.length() <= 1){
return s.length();
}
char[] arr = s.toCharArray();
Set<Character> set = new HashSet<>();
String lens = "";
for (int i = 0; i < arr.length; i++) {
int location = i;
while (location < arr.length){
if(set.contains(arr[location])){
lens += set.size()+","; //拿到目前子串的长度
set.clear(); //清空集合
break;
}else {
set.add(arr[location]);
}
location++;
}
if(location == arr.length-1){
//最后一个子串都读到了末尾,不需要在往后遍历了
break;
}
}
String[] len = lens.split(",");
int[] length = new int[len.length];
for (int i = 0; i < length.length; i++) {
length[i] = Integer.parseInt(len[i]);
}
Arrays.sort(length);
return length[len.length-1];
}
}
没错,就是暴力,
大佬的思路:
class Solution {
public int lengthOfLongestSubstring(String s) {
// 记录字符上一次出现的位置
int[] last = new int[128];
for(int i = 0; i < 128; i++) {
last[i] = -1;
}
int n = s.length();
int res = 0;
int start = 0; // 窗口开始位置
for(int i = 0; i < n; i++) {
int index = s.charAt(i);
start = Math.max(start, last[index] + 1);
res = Math.max(res, i - start + 1);
last[index] = i;
}
return res;
}
}
滑动窗口:
题目说了s由英文字母、数字、符号和空格组成, 所以Ascii码表可以覆盖。
创建一个与AscII码表相对应的128长度的数组,用来记录字符上次出现的位置,初值都为-1。
遍历s,用int接字符,拿到的就是ASCII码值。
start为窗口开始的位置,如果窗口遇到了重复字符,start就会更新至重复字符上次出现位置的后面。(遇到重复的就"掐头")
res 实时更新,得到一个子串的长度,就比较得到max。 而不用把所有长度放进字符串再处理字符串,排序。
效率高很多。