codeTop100题(1)3. 无重复字符的最长子串

91 阅读1分钟

1. 题目

3. 无重复字符的最长子串

2. 思路

考虑使用双指针,如果字符没有重复,则右指针继续后移;如果字符重复了,把左指针一直右移,一直到字符不重复为止,右移的时候需要把遍历到的都移除。

3. 代码

3.1 第一版答案

第一版答案没有通过下面的case:

""

class Solution {
    public static int lengthOfLongestSubstring(String s) {
        int i = 0, j = 0;
        int lMax = 0, rMax = 0;
        Set<Character> set = new HashSet<>();
        while (j < s.length()) {
            if (set.contains(s.charAt(j))) {
                if (j - 1 - i > rMax - lMax) {
                    rMax = j - 1;
                    lMax = i;
                }
                while (s.charAt(j) != s.charAt(i)) {
                    i++;
                }
                i++;
                j++;
            } else {
                set.add(s.charAt(j));
                j++;
            }
        }
        return rMax - lMax + 1;
    }
}

分析:

这段代码有两个问题:

  1. 计算最大长度的地方应该是在没有出现重复的时候
  2. 代码中在字符出现重复的时候,把右指针进行了右移,导致右指针所在字符这个长度没有被计算

3.2 版本2

class Solution {
    public static int lengthOfLongestSubstring(String s) {
        int i = 0, j = 0;
        int max = 0;
        Set<Character> set = new HashSet<>();
        while (j < s.length()) {
            if (set.contains(s.charAt(j))) {
                
                while (s.charAt(j) != s.charAt(i)) {
                    i++;
                }
                i++;
            } else {
                if (j - i + 1 > max) {
                    max = j - i + 1;
                }
                set.add(s.charAt(j));
            }
            j++;
        }
        return max;
    }
}

这个版本还是无法通过 "tmmzuxt"这个case。

分析:

因为在左指针右移的时候没有将遍历到的字符移除set。

3.3 版本3

class Solution {
    public static int lengthOfLongestSubstring(String s) {
        int i = 0, j = 0;
        int max = 0;
        Set<Character> set = new HashSet<>();
        while (j < s.length()) {
            if (set.contains(s.charAt(j))) {
                
                while (s.charAt(j) != s.charAt(i)) {
                    set.remove(s.charAt(i));
                    i++;
                }
                set.remove(s.charAt(i));
                i++;
            } else {
                if (j - i + 1 > max) {
                    max = j - i + 1;
                }
                set.add(s.charAt(j));
                j++;
            }
        }
        return max;
    }
}