leetcode-3-无重复字符的最长子串
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
class Solution{ /* 暴力法是遍历每一个字符串,检查是不是含有子串 如果我们从索引i到i-1之间的子字符串已经被检查为没有重复字符,我们只需要检查对应的字符是否已经存在字符串中 要检查一个字符串是否已经存在子字符串中,我们可以检查整个子字符串,这将产生了一个复杂度为O(n2)的算法 通过使用hashset作为滑动窗口,我们可以用O(1)的时间来完成对字符串是否在当前的子字符串中的检查 滑动窗口是数组/字符串问题中的常见的抽象,窗口通常是在数组/字符串中由开始和结束索引定义的一系列元素的集合 即[i,j),而滑动窗口是可以将两个边界向某一方向滑动的窗口, 我们使用hashset将字符串储存在当前窗口[i,j)中,然后我们向右滑动索引j,如果它不在hashset中 我们将继续滑动j,直到s[j]已经存在于hashset中,此时,我们找到的没有重复字符的最长子字符串会将索引 i开头,如果我们对所有的i都这样做,就可以找到答案 */ public int lengthOfLongestSubstring(String s) { int n = s.length(); // 建立hashset Set<Character> set = new HashSet<>(); // 定义最大值 int ans = 0; // 定义窗口值的左右 int i = 0, j = 0; //当窗口的左右都小于数组的长度的时候 while (i < n && j < n) { // 判断hashset中是不是存在s.charAt(j) // 如果不存在加到滑动窗口里 if (!set.contains(s.charAt(j))){ set.add(s.charAt(j++)); // 获取最大值 ans = Math.max(ans, j - i); } else { //前面找到当前滑动窗口里面无重复子串的最大值,现在将滑动窗口往后滑动一个位置 set.remove(s.charAt(i++)); } } return ans; } }