力扣刷题笔记-03

03 无重复字符的最长子串

我的思路

明确问题
  1. 怎么判断字符串是不是重复
    答:hashset的contains,把字符放进集合里。

chatGPT

滑动窗口
  1. 定义两个指针,分别是left和right,用来指向不重复的子字符串。初始时候两个字符串都指向字符串的开头
  2. 用HashSet存储当前窗口里的元素,用int max变量存储最大的子串长度
  3. 开始遍历,right指针移动,先判断是不是包含在集合里,不包含的话放进去,用Math.max判断最大子串;包含的话,left指针所在的那个字符从集合里面移除来,left右移。
  4. 重复3
  5. while循环的出口在right指针指向最后一个字符的时候

这个算法目前的时间复杂度挺高,应该用hashmap存储字符和索引

class Solution {
    public int lengthOfLongestSubstring(String s) {
        if (s == null || s.length() == 0) {
            return 0;
        }
        // 达摩克利斯之剑始终高悬,裁员的屠刀时刻垂直
        // 用HashSet来保存滑动窗口里面的数据
        HashSet<Character> set = new HashSet<>();
        // 用来记录无重复的子串的长度
        int maxLength = 0;

        // 初始时刻,窗口两端的指针都指向0
        int left = 0;
        int right = 0;
        while (right < s.length()) {
            char currentChar = s.charAt(right);
            if (!set.contains(currentChar)) {
                // 字符放进滑动窗口里
                set.add(currentChar);
                /**
                 * 这行代码是我认为整个算法最巧妙的地方
                 * 为什么要取max呢?
                 * 滑动窗口只保证里面的字符串是不重复的,不管是不是最长的
                 * 所以我们每次窗口滑动的时候,就要计算一下最大长度,保存下来。
                 */
                maxLength = Math.max(maxLength, right - left + 1);
                // right指针右移
                right++;
            } else {
                // 进到这里说明有重复的元素,left指针右移
                set.remove(s.charAt(left));
                left++;
            }
        }
        return maxLength;
    }
}
posted @ 2023-09-22 16:34  大海0101  阅读(4)  评论(0编辑  收藏  举报