题目内容为:从字符串s中找出不包含重复字符的最大连续子字符串长度.
public static void main(String[] args) {
String str = "aaafc";
List list = new ArrayList();
int max = 0;
int len = str.length();
int c = 0;
for (int m = 0; m < len; m++) {
for (int i = c; i < len; i++) {
if (!list.contains(str.charAt(i))) {//list中不包含则添加对象
list.add(str.charAt(i));
} else {//遇到重复字符时获取该连续字符串长度,并把list清空
c++;
if (max < list.size()) {
max = list.size();
}
list.removeAll(list);
}
}
}
System.out.println(max);
}
以下为引用:
要求实现尽可能高效.
问:是否存在O(n)复杂度的算法
答案(Java语言描述,经过测试):
下面的两个算法,一个是简单算法(利用哈希表),另一个是O(n)复杂度的算法。
/**
* 简单算法, 利用 哈希集合 保存遍历过的字符串
* @param str
* @return
*/
static int myFoo(String str){
int ret = 1;// 如果字符串只有一个字符,返回1
int startP = 0;// 最长连续不重复字符串的 起始位置
int endP = 0;// 最长连续不重复字符串的 结束位置
for (int i = 0; i < str.length(); i++) {// 从第i个字符开始寻找
char c = str.charAt(i);
HashSet set = new HashSet();
set.add(""+c);
for (int j = i+1; j < str.length(); j++) {// 遍历后面的字符串
// 如果当前字符已经在 哈希集合 中,break
if ( set.contains(""+str.charAt(j)) ){
if ( set.size()> ret ){
ret = set.size();
startP=i;
endP = j;
}
break;
} else {
// 如果没有出现在 哈希集合中,放入 hash集合,继续
set.add(""+str.charAt(j));
if (j==str.length()-1){// 遍历到末尾,仍没有出现重复字符
if ( set.size()> ret ){
ret = set.size();
startP=i;
endP = j+1;
}
}
}
}
}
// System.out.println(ret);
System.out.println("myFoo lstr:"+str.substring(startP,endP));
return ret;
}
/**
* O(n)复杂度的算法
* 算法思想:保存 字符最后出现的位置, 利用该位置信息计算字符串长度
* @param str
* @return
*/
static int foo( String str ){
int ret = 0; // 将返回的 最长不重复子串长度
int retStrPos = 0;
int max = 0;// 当前的最长不重复子串长度
int[] lastPos = new int[26]; // 小写英文字符 最后出现的位置
Arrays.fill(lastPos, -1);
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
// 检查是否出现过
int lastP = lastPos[c-'a'];
if ( lastP != -1 ){// 出现过
max = Math.min( max+1, i-lastP);
} else {
max++;
}
if ( max > ret ){// 如果当前长度较大,赋值给 ret
ret = max;
retStrPos = i;
}
lastPos[c-'a'] = i;// 更新最后出现位置 数组
}
// 输出得到的 最长字符串
// System.out.println("DEBUG lstr:"+ str.substring(retStrPos-ret+1,retStrPos+1) );
return ret;
}