题目
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
解题思路
- 双指针+滑动窗口: 两个指针就是窗口的两个边框.
- 就是通过缩放窗口,也就是移动左窗框的指针,将最大的子串框出来.
具体代码逻辑,请看注释.
代码
class Solution {
public int lengthOfLongestSubstring(String s) {
int length = s.length();
// 存储最长字符串
int max = 0;
// 用来装无重复字符,和其最大下标的
Map<Character,Integer> map = new HashMap();
char[] sc = s.toCharArray();
// 记录窗口的开始位置,窗口从左往右移
int start = 0;
for(int i = 0 ; i < length ; i++){
if(map.containsKey(sc[i])){
// 如果存在,判断其是在窗口外边还是里面.
// 如果在窗口外面,也就是开始,则不管(之所以移动就是因为有重复字符,往回移动不扯淡嘛))
// 在里面,则将窗口移动到此位置
start = Math.max(map.get(sc[i]),start);
}
// 每走一步,就要和最大值比一下,如果大,就更新.i就是窗口的右边框
max = Math.max(i - start + 1,max);
// key存的是: 字符,用来比较的,value存的是: 如果比较成功,用来和start,也就是左边窗口比较的下标
map.put(sc[i],i+1);
}
return max;
}
}