题目

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

示例 1:

输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:

输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:

输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

我的题解

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int left = 0, right = 0, length = 0, maxLength = 0;//定义了两个指针,左指针left和右指针right,用于指向字符串,以及当前无重复字符的子串length,还有maxLength保存最大无重复的最长子串
        HashSet<Object> set = new HashSet<>();//set集合存储字符
 
        //left到right截取子串
        while (right < s.length()) {//当右指针大于等于字符串长度时结束循环
            if (!set.contains(s.charAt(right))) {//如果集合当中不包含右指针指向的字符
                set.add(s.charAt(right));//不包含,意味着该字符添加进set集合无重复
                right++;//右指针右移
                length++;//当前子串的长度可以加1,因为右指针右移
                if (length > maxLength) {//当前子串长度比最大长度还要大的情况下,更新最大长度
                    maxLength = length;//更新最大长度
                }
                
            } else {//包含右指针指向的字符,左指针移动
                while (set.contains(s.charAt(right))) {//当集合中包含右指针的时候,移动左指针
                    set.remove(s.charAt(left));//在集合中移除->左指针指向的字符与右指针指向的字符相同的情况下
                    left++;//左指针右滑
                    length--;//当前子串长度减1
                }
                set.add(s.charAt(right));//走到这里,意味着集合当中并不包含右指针指向的字符,因此将该字符存入集合当中
                length++;//当前子串长度加一
                right++;//右指针右滑,准备下一次循环
            }
        }
        return maxLength;//右指针超出范围,循环结束,返回maxLength--无重复字符的最长子串
    }
}

总结

用到了滑动窗口,但是这种效率依旧不是很高,我见K神的题解还用到了哈希表进行存取,我见底下有人说有点小瑕疵,目前先这样吧,毕竟我原来都是暴力破解,谁能一下子就完美呢?嘻嘻

20240919142005

又活一天已经很棒了