/*
*找出最长无重复子串的长度:时间复杂度为o(n)
*解题思路:最优化问题,使用动态规划,但是动态规划直接解题的话时间复杂度
*可能是o(n^2)吧,所以它就出来了,hashmap。所以本题采用动态规划+hashmap实现,还要
*用一个常量记录第i个字符前一个i-1字符的上次出现的位置,为啥要记录它呢?这是因为动态
*规划在作出选择的时候要考虑:d[i] = i – 前一次i位置字符出现位置,或者d[i] = d[i-1] + 1(
*这是因为i-1字符的上次出现的位置在i字符上一次出现位置前面,所以不能取i – 前一次i位置字符出现位置)
*/
import java.util.*;
public class NoSameSubstring{
public static int findMax(String str){
char[] a = str.toCharArray();
HashMap<Character, Integer> map = new HashMap<>();
int n = a.length;
int[] d = new int[n + 1];
//记录i-1字符前一次出现的位置,如果没有出现就置为-1
int pre = 0;
d[1] = 1;
//在hashmap中将第一个元素添加进去
map.put(a[0],1);
//从d[2]开始计算,i=2时,i-1上一次出现的位置,1是第一次出现,所以pre=0
for(int i = 2; i <= n; i++){
//首先从hashmap中获取i上一次出现的位置,如果为null,没有出现,所以当做0看
Integer currentPreIndex = map.get(a[i-1]);
if(currentPreIndex == null){
currentPreIndex = 0;
}
//然后获取i-1的上一次出现的位置,即pre的值,所以完成一次d[i]后记得
//更新pre的值,比较pre和currentPreIndex的大小
if(pre < currentPreIndex){
d[i] = i – currentPreIndex;
}else{
d[i] = d[i – 1] + 1;
}
//更新pre是有技巧的吧???pre只能变大,为啥??
//看:”abddab”,在计算最后一个b时,pre不能是a的前一个位置吧,只能是d的前一个
//位置,再看”adbdab”
if(pre < currentPreIndex){
pre = currentPreIndex;
}
//装入hashmap,覆蓋位置信息
map.put(a[i-1],i);
}
int result = Integer.MIN_VALUE;
System.out.println(“表d:”);
for(int i = 1; i <= n; i++){
if(result < d[i])result = d[i];
System.out.printf(“%2d”,d[i]);
}
System.out.println();
System.out.println(map);
return result;
}
//随机生成字符串,用于测试
public static String getRandomString(int length) { //length表示生成字符串的长度
String base = “abcde”;
Random random = new Random();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < length; i++) {
int number = random.nextInt(base.length());
sb.append(base.charAt(number));
}
return sb.toString();
}
public static void main(String[] args){
//String str = “abddab”;
//String str = “aabcb”;
String str = getRandomString(10);
System.out.println(“结果为:” + findMax(str));
System.out.println(“原字符串:” + str);
}
}
参考文章
http://blog.csdn.net/xiaoyukid/article/details/6041697