这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战
1.LeetCode无重复字符的最长子串
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
可以使用滑动窗口实现,窗口从左往右慢慢拉大,只要保证窗口字符不重复,那么移动到最后时,最大的窗口值就是目标值。
使用两个指针表示窗口的边界,左边界为最开始的位置,右边界往右边一个一个遍历字符,同时用一个哈希表记录遍历的字符,key存储字符,value存储下标,可以当做右指针,当做窗口内的字符,同时可以比较方便的判断字符是否重复,如果遇到了重复存在哈希表内的字符时就需要移动左指针,将左指针往右移动到重复字符的位置,以保证窗口字符不重复,后面在正常添加字符及其下标到哈希表,最后再取最大的窗口大小,就是两个下标差。
例如aabcab 左指针默认在a字符左边,右指针指向a字符,左指针-1,右指针0,最大长度默认为0,哈希表内容为空,遍历字符串,用右指针往后移动 第一次为(a)abcab 第一次获取下标0字符为a,查询a字符不存在哈希表,将a字符和下标添加到哈希表,此时最大字符串长度为1(右下标-左下标)。 第二次为a(a)bca 往后移动遇到字符a,与哈希表字符比较发现是重复的,此时需要移动左指针,将左指针往右移动到重复字符处下,取最大的下标值。同时最大字符长度还是1。 第三次为a(ab)ca 继续往右遍历字符b,比较哈希表,无重复,添加字符,取最大字符长度为2。 第四次为a(abc)a 继续往右遍历字符c,比较哈希表也无重复,添加字符后取最大长度为3。 第五次为aa(bca) 继续往右遍历字符a,发现与哈希表重复,需要移动左指针,此时字符最大长度为3。
public int lengthOfLongestSubstring(String s) {
// 最大长度
int maxLength = 0;
// 左指针
int leftPointer = -1;
// 哈希表判断字符是否重复
Map<Character, Integer> map = new HashMap<Character, Integer>();
// 当前遍历的字符
char currentChar;
// 右指针循环遍历
for (int rightPointer = 0, length = s.length(); rightPointer < length; rightPointer++) {
currentChar = s.charAt(rightPointer);
if (map.containsKey(currentChar)) {
// 哈希表里面存在,指针往后移动到存在的字符处,max保证往后移动
leftPointer = Math.max(leftPointer, map.get(currentChar));
}
// 添加当前字符及其下标到哈希表
map.put(currentChar, rightPointer);
// 取得子字符串最大值
maxLength = Math.max(maxLength, rightPointer - leftPointer);
}
return maxLength;
}