class Solution {
public int lengthOfLongestSubstring(String s) {
int len = s.length();
if(len == 0) {
return 0;
}
int st = 0;
int ed = 0;
int ans = 1;
boolean[] judge = new boolean[128];
judge[s.charAt(st)] = true;
while(++ed < len) {
if(judge[s.charAt(ed)]) {
while(s.charAt(st) != s.charAt(ed)) {
judge[s.charAt(st++)] = false;
}
st++;
}
judge[s.charAt(ed)] = true;
ans = Math.max(ans, ed - st + 1);
}
return ans;
}
}
上次面试官让我基于上面一个做法进一步优化,我就优化成下面这样。
思路就是将数组修改为上次出现的下标位置+1。
如果出现过s.charAt(ed),我直接将滑动窗口的起点修改为index[s.charAt(ed)]。
注意,这里判定s.charAt(ed)是否出现过不是看index[s.charAt(ed)]是否为0,而是看index[s.charAt(ed)]是否大于st,因为如果这个数上次出现是在起点之前,那也相当于没出现在目前的窗口里。
class Solution {
public int lengthOfLongestSubstring(String s) {
int len = s.length();
if(len == 0) {
return 0;
}
int st = 0;
int ed = 0;
int ans = 1;
// 记录上次该数出现的下标+1(为0代表没出现过)
int[] index = new int[128];
index[s.charAt(st)] = 1;
while(++ed < len) {
// 代表在st到ed范围中出现过这个数
st = Math.max(st, index[s.charAt(ed)]);
index[s.charAt(ed)] = ed + 1;
ans = Math.max(ans, ed - st + 1);
}
return ans;
}
}