无重复字符的最长子串
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例 :
输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
思路:用滑动窗口:滑动窗口实际上是通过双指针实现的,[left,right]之间的范围就是窗口。通常用于解决字符串、数组相关的问题。比如最小子串等。
1、定义一个map集合(k,v),key值为字符串的字符,value值为字符的索引加1,加1表示该字符是第几个字符。
2、定义子串开始的位置是start,结束位置为end,初始值都为0,指向第一个字符。
3、end不断后移过程中会出现重复的字符,可以用map中的containsKey(key)方法来判断map中是否出现重复的key值。map中的containsKey(key)方法是判断该key在map中是否已经存在,如果存在则返回true,如果不存在则返回false。定义一个ans记录窗口的大小(也就是子串的长度),ans=Math.max(end-start+1,ans)。
4、不存在,则将该字符放入map集合中,value值记为索引加1.end后移一位。存在,则获取该字符的value值,重新定义start,start=Math.max(value,start),计算此时的窗口大小,与之前求的窗口大小取最大值。
5、将获取的字符放入map集合中,value值为end+1。
例:awbwsd
a的value值为1,表示a是第1个字符。map中不存在key值a,将a放入map中,遍历到第四个字符w时,start=0,end=3,ans=3,w在map中已经存在,value值为2,改变start值,start=Math.max(2,0)=2,ans=Math.max(3-2+1,3)=3,修改w的在、value值为end+1=4。
end=3,start=0,ans=3
a | w | b |
---|---|---|
1 | 2 | 3 |
start=2; end=3; ans=3; w.vaule=end+1;
a | w | b |
---|---|---|
1 | 4 | 3 |
satrt=2; end=5; ans=4
a | w | b | s | d |
---|---|---|---|---|
1 | 4 | 3 | 5 | 6 |
代码实现:
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入一个字符串:");
String s=sc.next();
System.out.println(lengthOfLongestSubstring(s));
}
public static int lengthOfLongestSubstring(String s) {
int n=s.length();
int ans=0;
Map<Character, Integer> map=new HashMap<>();//map存字符串
for(int end=0,start=0;end<n;end++) {
char a=s.charAt(end);
if(map.containsKey(a)) {//判断key值是否已经存在
start=Math.max(map.get(a), start);//该字符是重复的,start指针向后移
}
ans=Math.max(ans, end-start+1);//保存子串的最大长度
map.put(s.charAt(end), end+1);//将字符和对应的value值放入map中
}
return ans;
}