Given a string, find the length of the longest substring without repeating characters.
Examples:
Given "abcabcbb"
, the answer is "abc"
, which the length is 3.
Given "bbbbb"
, the answer is "b"
, with the length of 1.
Given "pwwkew"
, the answer is "wke"
, with the length of 3. Note that the answer must be a substring, "pwke"
is a subsequence and not a substring.
思路:
这个题的意思是让我们找出一个字符串中最大子串的长度,且子串必须是无重复的。例如"abcabcbb"
这个字符串,我们可以看出它的无重复最大子串可能是"abc"
、"bca"
、"cab"
这几个。所以我们应该给出最大长度3。
显然这种情况下我们最少要遍历字符串一次。那么首先我们需要一个能方便地判断存储的数据是否重复的数据结构。可能你首先想到了hashmap,使用hashmap是可以的,但是hashmap 存储的是key-value 键值对,而我们每次只需要存储一个值就行了。
- 遍历字符串,如果当前的字符在hashset中不存在,那么就**添加到hashset **中。
- 如果hashset中存在当前字符串,首先判断hashset和max的大小,max始终是这两个中最大的数。
- 更新max后,清空重复字符及其位置之前的所有字符,如
"abcabcbb"
当我们判断到第四位"a"
的时候,hashset中已经有"abc"
三个字符了,那么我们需要删除"a"
。 - 遍历结束返回hashset和max中最大的值。这是因为max中存的是历史最大长度,而hashset的长度当前子字符串最大的长度,所以我们需要返回他们中最大的那个值。
代码实现:
class Solution {
public int lengthOfLongestSubstring(String s) {
HashSet<Character> tempMap = new HashSet< Character>();
int max = 0;
int begin = 0;
for (int i = 0; i < s.length(); i++) {
if (tempMap.contains(s.charAt(i))) {
if (tempMap.size() > max) {
max = tempMap.size();
}
while (tempMap.contains(s.charAt(i))) {
tempMap.remove(s.charAt(begin));
begin++;
}
}
tempMap.add(s.charAt(i));
}
return max > tempMap.size() ? max : tempMap.size();
}
}
考一考:
更改本问题的返回值,要求返回所有的最长子串(最长的子串可能不唯一),那么该怎么做呢?