class Solution {
public int lengthOfLongestSubstring(String s) {
if (s == null || s.length() <= 0) {
return 0;
}
int leftIndex = -1;
int result = 0;
Map<Character, Integer> leftIndexMap = new HashMap<Character, Integer>();
char[] charArray = s.toCharArray();
for (int i = 0; i < s.length(); i++) {
if (leftIndexMap.containsKey(charArray[i])) { // 当前数字 在之前遍历时出现过,就更新 窗口左边界
leftIndex = Math.max(leftIndex, leftIndexMap.get(charArray[i]));
}
leftIndexMap.put(charArray[i], i);
result = Math.max(result, i - leftIndex); // 计算 当前结果
}
return result;
}
}
// //动态规划+哈希
// class Solution {
// public int lengthOfLongestSubstring(String s) {
// //特殊条件
// int len = s.length();
// if(s==null || len==0){
// return 0;
// }
// // if(len==1){
// // return 1;
// // }
// //用动态规划
// //初始化
// // 优化空间
// int pre = 1;//上一个状态
// int max = pre;//最大值
// //hashmap记录上个重复字符索引
// HashMap<Character,Integer> map = new HashMap<Character,Integer>();
// map.put(s.charAt(0),0);
// for(int i=1;i<len;i++){//遍历字符串
// char ch = s.charAt(i);
// Integer charIndex = map.get(ch);
// if(charIndex==null){//左侧无重复
// pre+=1;
// map.put(ch,i);
// }else{
// int j= map.get(ch);//左侧有重复,获得最后出现的下标
// if((i-j)>pre){
// pre+=1;
// }else if((i-j)<=pre){
// pre = i-j;
// }
// map.put(ch,i);
// }
// if(pre>max) max=pre;
// }
// return max;
// }
// }
//动态规划+线性查找 O(N^2) O(1)
// class Solution {
// public int lengthOfLongestSubstring(String s) {
// //特殊条件
// int len = s.length();
// if(s==null || len==0){
// return 0;
// }
// //用动态规划
// //初始化
// int[] dp = new int[len];//动态规划列表
// dp[0] = 1;
// for(int i=1;i<len;i++){//遍历字符串
// int index = -1;
// char si = s.charAt(i);
// for(int j=0;j<i;j++){//查找重复字符,用线性查找
// if(si==s.charAt(j)){//找到重复字符,得到重复字符的索引
// index = j;
// }
// }
// if(index==-1){//i左侧没有重复字符
// dp[i] = dp[i-1]+1;
// }else if((i-index)>dp[i-1]){//重复字符在上一个最长无重复字符串外面
// dp[i] = dp[i-1]+1;
// }else if((i-index)<=dp[i-1]){//重复字符位于上一个最长无重复字符串中
// dp[i] = i-index;
// }
// }
// int res = 0;
// for(int m:dp){
// if(m>res) res=m;
// }
// return res;
// }
// }