题目
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.
翻译
给定一个字符串,找出最长的子串,其中子串不包含任何重复的字符
思路
基本思路是遍历字符串,求出以i
结尾的最长不重复子串v(i)
要想求出v(i)
需要知道起始字符索引j,开始的时候可以设j=0
所以问题转化为了:对于当前的(i,j),当i = i + 1时如何更新j
最容易想到的思路就是,如果保存了当前(i,j)的所有字符集和对应的索引
,那么当i=i+1
时,如果字符s[i+1]在集合内,则将j设置为出现该字符的下一个位置
,如果不在,将当前字符放入集合中即可。
复杂度
O(n)(近似,可以使用数组来优化,比较简单,这里就不上代码了)
代码
import java.util.HashMap;
import java.util.HashSet;
class a3 {
public int lengthOfLongestSubstring(String s) {
int result = 0;
HashMap<Character, Integer> map = new HashMap<>();
for(int i = 0, j = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if(map.containsKey(ch)) {
/*
当字符出现过时,有两种情况
1.这个字符在j左边,这个时候可以不理睬
2.这个字符出现在j右边,这个时候需要将j移动到这个位置+1
因为求的是以i结尾的最长不重复子串
*/
j = Math.max(j, map.get(ch) + 1);
}
/*
两个作用:
1.加入新的字符
2.更新旧字符的最新位置
*/
map.put(ch, i);
result = Math.max(result, i - j + 1);
}
return result;
}
}