给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
算法分析,首先因为要找到不含有重复字符的最长子串的长度,因此我们首先要能够判断当前字符是否已经遍历过,很容易想到一个比较简单的方法就是HashMap,将遍历到的字符存入map中,之后通过containsKey判断是否遍历过。
接下来思考这个题目的解法,这个题目我们需要遍历整个字符串,此外需要一个指针,该指针在初始时指向字符串的第一个元素。在后续当检测到重复字符时需要指向重复字符的下一位。
当字符串不在map中时,将字符串存到map中,然后计算当前的length值并与最大值进行比较,取两者的最大值。因为当我们调整pointer的位置后,可能导致length的长度降低。当字符串在map中时,利用滑动窗口思想,将pointer设置为map中重复元素的索引的下一位,然后修改重复元素的索引。
执行流程如下:
1. 将字符串转换为字符数组进行遍历;
2. 创建一个hashMap,主要用来存放字符以及其对应的索引;
3. 创建两个int类型的变量分别保存最大无重复子串的长度,以及指向最近无重复元素的指针;
4. 执行循环
-判断字符是否已经遍历过,没有遍历过将其直接存储进去;
-如果字符已经遍历过,调整pointer的位置,这里之所以比较用max函数进行比较是因为避免"abba"的情况,在这种情况下,当遍历到第二个a时会导致pointer从2降为1,从而导致错误的length
-最后计算length的长度
5. 返回结果
class Solution {
public int lengthOfLongestSubstring(String s) {
char[] charArray = s.toCharArray();
HashMap<Character, Integer> hashMap = new HashMap<>();
int length = 0;
int pointer = 0;
for (int i = 0; i < charArray.length; i++) {
if (!hashMap.containsKey(charArray[i])) {
hashMap.put(charArray[i], i);
} else {
pointer = Math.max(hashMap.get(charArray[i]) + 1, pointer);
hashMap.put(charArray[i], i);
}
length = Math.max(length, i - pointer + 1);
}
return length;
}
}