<刷题记录>无重复字符的最长子串
LeetCode 第 03 题:给定一个字符串,请你找出其中不含有重复字符的最长子串的长度。
示例 1
输入:"abcabcbb"
输出:3
解释:因为无重复字符的最长子串是"abc",其长度为3。
示例 2
输入:"bbbbb"
输出:1
解释:因为无重复字符的最长子串是 "b",其长度为 1。
示例 3
输入:"pwwkew"
输出:3
解释:因为无重复字符的最长子串是 "wke",其长度为 3。
注意:答案必须是子串的长度,"pwke" 是一个子序列,不是子串。
解法一:暴力法:
直接列出所有子串,然后每一个都判断是否有重复字符,用一个max计数变量记录最长无重复字符子串的长度.
由于耗时太长,LeetCode上直接超时了...
解法二:
思路:
如字符串为deabca
-
可以定义两个指针 i 和 j。
-
i 是慢指针,j 是快指针,当 j 遇到了一个重复出现的字符时,从慢指针开始一个一个地将 i 指针指向的字符从集合里删除,然后判断一下是否可以把新字符加入到集合里而不会产生重复。
-
把字符 d 删除后,i 指针向前移动一步,此时集合里还剩下:e, a, b, c,很明显,字符 a 还在集合里,仍然要继续删除。
-
把字符 e 删除后,集合里还剩 a,b,c,字符 a 还在集合里,继续删除慢指针 i 指向的字符 a。
-
集合里剩 b,c,可以放心地把新的字符 a 放入到集合里,然后快指针 j 往前移动一步。
通过这样不断尝试,每当新的字符加入到集合里的时候,统计一下当前集合里的元素个数,最后记录下最长的那个
public int lengthOfLongestSubstring(String s) { if(s == null || s.length() == 0) return 0; int max = 1;
// 定义一个集合,用来存储不重复的子串的字符 List<Character> list = new ArrayList<>(); //遍历字符串的每个字符,将其加入集合中,如果遇到重复字符,则从集合
//首部开始移除字符,直到不重复为止 for(int i = 0,j = 0;j<s.length();j++){ //判断是否包含重复字符 while(list.contains(s.charAt(j))){
//这里巨坑,不要用remove(index),要用remove(object) Character c = s.charAt(i); list.remove(c); i++; }
//如果不重复就将当前字符加入 list.add(s.charAt(j));
//更新max值 max = Math.max(max,list.size()); } return max; }