Leetcode 习题03 无重复字符的最长子串 详细流程解析

65 阅读2分钟

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

输入: s = "abcabcbb" 

输出:

解释:  因为无重复字符的最长子串是 "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;
    }
}