import java.util.HashMap;
import java.util.Map;
/**
* 1、start不动,end向后移动
* 2、当end遇到重复字符,start应该放在上一个重复字符的位置的后一位,同时记录最长的长度
* 3、怎样判断是否遇到重复字符,且怎么知道上一个重复字符的位置?--用哈希字典的key来判断是否重复,用value来记录该字符的下一个不重复的位置。
*/
/**
* 标签:滑动窗口
* 暴力解法时间复杂度较高,会达到 O(n^2) ,故而采取滑动窗口的方法降低时间复杂度
* 定义一个 map 数据结构存储 (k, v),其中 key 值为字符,value 值为字符位置 +1,加 1 表示从字符位置后一个才开始不重复
* 我们定义不重复子串的开始位置为 start,结束位置为 end
* 随着 end 不断遍历向后,会遇到与 [start, end] 区间内字符相同的情况,此时将字符作为 key 值,获取其 value 值,并更新 start,此时 [start, end] 区间内不存在重复字符
* 无论是否更新 start,都会更新其 map 数据结构和结果 ans。
* 时间复杂度:O(n)
*
*/
public class LengthOfLongestSubstring03 {
public static void main(String args[]){
String s = "aasdsdfcccasdg" ;
int i = lengthOfLongestSubstring(s);
System.out.println(i);
}
// 滑动窗口 从开始到结束 有重复的就重新开始记录
/**
* 手写一遍后需要注意:
* HashMap的写法 :new HashMap<>() 、containsKey 、Integer 、最先把map new出来
* @param s
* @return
*/
public static int lengthOfLongestSubstring(String s) {
//字符串的长度
int n = s.length();
//不重符字符串的最大长度
int ans = 0;
// 定一个map 降低时间复杂度
Map<Character, Integer> map = new HashMap<>();
//遍历这个字符串,不重复字符串的开始位置为start ,结束位置为end
for (int end = 0, start = 0; end < n; end++) {
//记录结束位置的这个字符是什么,如果map中不包含这个字符,则记录一下最长的长度
char alpha = s.charAt(end);
//2、如果map中包含这个字符,则start后移,重置这个字符的位置信息
if (map.containsKey(alpha)) {
start = Math.max(map.get(alpha), start);
}
// 1、如果map中不包含这个字符,则记录一下目前到这个字符的最长的长度,
ans = Math.max(ans, end - start + 1);
//map的key是结束位置的这个字符,value为这个字符开始不重复的位置
map.put(alpha, end + 1); }
return ans;
}
}
12-03
248
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)
08-22
479
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)
08-24
686
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)