方法一:循环遍历,采用Set保存数据,复杂度O(n^2)
private static Set<String> getSubList(String str) {
if (null == str || str.trim().length() == 0) {
return null;
}
Set<String> result = new HashSet<String>();
int maxLength = 0;
StringBuilder sb = new StringBuilder();
char[] array = str.toCharArray();
int length = array.length;
for (int i = 0; i < length; i++) {
int j = i + 1;
sb.delete(0, sb.length());
sb.append(array[i]);
while ((length - j) >= maxLength) {
sb.delete(0, sb.length());
for (; j < length; j++) {
if (sb.toString().contains(String.valueOf(array[j]))) {
break;
} else {
sb.append(String.valueOf(array[j]));
}
}
// System.out.println(j + "," + sb.toString());
if (sb.length() > maxLength) {
maxLength = sb.length();
result.clear();
result.add(sb.toString());
} else if (sb.length() == maxLength) {
result.add(sb.toString());
}
}
}
return result;
}方法2:
采用一个map来做中间缓存,用list保存结果,map的key存储的是字符,value存储的是该字符当前的位置,首先设置一个当前current位置,默认从0开始,那么从开始遍历字符串,如果map当中不包含这个字符,那么用这个字符当前所在的位置减去current位置,然后与最大长度做比较,选大的成为最大长度,然后把当前字符的以及位置放入map,同时把从current位置的字符到current+maxLength位置的字符组成子串放入一个list中,保存前需要判断当前list中已经保存的字符的长度是否大于将要保存的字符长度,小于则将list清除,复杂度
O(n)
public static List<String> getSubList2(String str){
if (null == str || str.trim().length() == 0) {
return null;
}
Map<Character,Integer> tempMap = new HashMap<>();
List<String> result = new ArrayList<String>();
StringBuilder sb = new StringBuilder();
int maxLength = 0;
char[] array = str.toCharArray();
int length = array.length;
int current = 0;
for(int i=0;i<length;i++){
if(tempMap.containsKey(array[i])){
current = Math.max(tempMap.get(array[i])+1,current);
// System.out.println((i-current+1)+","+maxLength);
if((i-current+1)>maxLength){
maxLength = i-current+1;
sb.delete(0, sb.length());
for(int j=current;j<current+maxLength;j++){
sb.append(array[j]);
}
if(result.size() > 0){
if(result.get(0).length()<maxLength){
result.clear();
}
}
result.add(sb.toString());
}else if((i-current+1) == maxLength){
sb.delete(0, sb.length());
for(int j=current;j<current+maxLength;j++){
sb.append(array[j]);
}
if(result.size() > 0){
if(result.get(0).length()<maxLength){
result.clear();
}
}
result.add(sb.toString());
}
}else{
// System.out.println((i-current+1)+","+maxLength);
if((i-current+1)>maxLength){
maxLength = i-current+1;
sb.delete(0, sb.length());
for(int j=current;j<current+maxLength;j++){
sb.append(array[j]);
}
if(result.size() > 0){
if(result.get(0).length()<maxLength){
result.clear();
}
}
result.add(sb.toString());
}else if((i-current+1) == maxLength){
sb.delete(0, sb.length());
for(int j=current;j<current+maxLength;j++){
sb.append(array[j]);
}
if(result.size() > 0){
if(result.get(0).length()<maxLength){
result.clear();
}
}
result.add(sb.toString());
}
}
tempMap.put(array[i], i);
}
// System.out.println(maxLength);
return result;
}
本文介绍了两种不同的算法来寻找给定字符串中最长的不含重复字符的子串。第一种方法使用循环遍历和哈希集,其时间复杂度为O(n²);第二种方法通过运用哈希映射优化了查找过程,实现O(n)的时间复杂度。
1102

被折叠的 条评论
为什么被折叠?



