给定一个字符串,找到最长子字符串的长度而不重复字符。例如,对于“ abcabcbb”,不重复字母的最长子字符串为“ abc”,其长度为3。对于“ bbbbb”,最长子字符串为“ b”,长度为1。
分析
解决此问题的基本思想是使用额外的数据结构来跟踪滑动窗口中的唯一字符。为此,数组和哈希集均适用。
Java解决方案1
第一种解决方案类似于CC 150中的“确定字符串是否具有所有唯一字符”问题。我们可以使用标志数组来跟踪最长子字符串的现有字符,而无需重复字符。
public int lengthOfLongestSubstring(String s) {
if(s==null)
return 0;
boolean[] flag = new boolean[256];
int result = 0;
int start = 0;
char[] arr = s.toCharArray();
for (int i = 0; i < arr.length; i++) {
char current = arr[i];
if (flag[current]) {
result = Math.max(result, i - start);
//循环更新新的起点
//并重置标志数组
//例如abccab,它涉及到第二个c时,
// //将其从0更新为3,
for (int k = start; k < i; k++) {
if (arr[k] == current) {
start = k + 1;
break;
}
flag[arr[k]] = false;
}
} else {
flag[current] = true;
}
}
result = Math.max(arr.length - start, result);
return result;
}
Java解决方案2-HashSet
使用HashSet可以大大简化代码。
public int lengthOfLongestSubstring(String s) {
if(s==null||s.length()==0){
return 0;
}
HashSet<Character> set = new HashSet<>();
int result = 1;
int i=0;
for(int j=0; j<s.length(); j++){
char c = s.charAt(j);
if(!set.contains(c)){
set.add(c);
result = Math.max(result, set.size());
}else{
while(i<j){
if(s.charAt(i)==c){
i++;
break;
}
set.remove(s.charAt(i));
i++;
}
}
}
return result;
}