1、题目描述
2、代码详解
import java.util.HashMap;
import java.util.Map;
public class LengthOfLongestSubstring_3 {
public static void main(String[] args){
String s = "abcabcbb";
System.out.println(lengthOfLongestSubstring(s));
}
public static int lengthOfLongestSubstring(String s){
int n = s.length();
int ans = 0;
// 滑动窗口,i左边端点,j右边端点
Map<Character, Integer> map = new HashMap<>();
for (int j = 0, i = 0; j < n; j++){
// 如果窗口中包含当前j位字符
if(map.containsKey(s.charAt(j))){
// 左边端点 移动到 “相同字符的下一个位置,或者i当前位置,取两者靠右的位置”,这样操作防止i向左移动
/*
如果不去两个中的最大值,而是一直取 s.charAt(j) 的话 ,可能会出现 某一字符的相同字符在很靠前的位置,
这样获取的i 就会比当前 的i 要小,出现了i 左移的情况
例如 abcdefcma 到第二个c的时候 i变成了 3,
但到第二个 a的时候如果取第一个a的位置,而不是a和当前i的最大值, i就变成了1,左侧索引左移
*/
i = Math.max(map.get(s.charAt(j)), i);
}
//比对当前无重复字段长度和储存的长度,选最大值并替换
//j-i+1是因为此时i,j索引仍处于不重复的位置,j还没有向后移动,取的[i,j]长度
ans = Math.max(ans, j-i+1);
// 将当前字符为key,下一个索引为value放入map中
// value为j+1是为了当出现重复字符时,i直接跳到上个相同字符的下一个位置,if中取值就不用+1了
map.put(s.charAt(j), j+1);
}
return ans;
}
}
class Solution {
public int lengthOfLongestSubstring(String s) {
int[] last = new int[128];
Arrays.fill(last, -1);
int start = 0;
int ans = 0;
for (int i = 0; i < s.length(); ++i) {
if (last[s.charAt(i)] != -1)
start = Math.max(start, last[s.charAt(i)] + 1);
last[s.charAt(i)] = i;
ans = Math.max(ans, i - start + 1);
}
return ans;
}
}
class Solution:
def lengthOfLongestSubstring(self, s):
last = [-1] * 128
ans = 0
start = 0
for i, ch in enumerate(s):
if last[ord(ch)] != -1:
start = max(start, last[ord(ch)] + 1)
ans = max(ans, i - start + 1)
last[ord(ch)] = i
return ans
https://www.bilibili.com/video/BV1CJ411G7Nn?from=search&seid=11912112177072333241