算法题之——最大子串
题目:给定一字符串只包含数字,请写一个算法,找出该字符串中的最长不重复子串(不重复是指子串中每一元素不同于子串中其他元素)
如: “120135435”最长不重复子串为 “201354”
代码:
方法一:
//辅助数组,o(n*n)
private static String noRepeatSubString(String str){
int a[] = new int[10];
int maxlength = 0;
int maxindex = 0;
int j;
for(int i=0;i<str.length();i++){
for(j=0;j<10;j++)
a[j] = 0;
char c = str.charAt(i);
a[c-'0'] = 1;
for(j=i+1;j<str.length();j++){
if(a[str.charAt(j)-'0']==0){
a[str.charAt(j)-'0'] = 1;
}else{
if(maxlength<j-i){
maxlength = j-i;
maxindex = i;
}
break;
}
}
if((j==str.length())&&(j-i>maxlength)){
maxlength = j-i;
maxindex = i;
}
}
System.out.println(maxindex);
return str.substring(maxindex, maxindex+maxlength-1);
}
方法二:
/**
* 数组dp存储到下标i的最大子数组长度
* 比如字符串"aabcdb"
* 则dp[0]=1(a),dp[1]=1(a),dp[2]=2(ab),dp[3]=3(abc),dp[4]=4(abcd),dp[5]=3(cdb)
* o(n*n)
* 可改进
* @param str
* @return
*/
private static String noRepeatSubString1(String str){
int dp[] = new int[str.length()];
dp[0] = 1;
int maxlen=0,maxindex = 0;
int last_start = 0;
for(int i=1;i<str.length();i++){
for(int j=i-1;j>=last_start;j--){
if(str.charAt(i)==str.charAt(j)){
dp[i] = i-j;
last_start = j+1;
break;
}else if(j==last_start){
dp[i] = dp[i-1]+1;
}
}
if(dp[i]>maxlen){
maxlen = dp[i];
maxindex = i+1-maxlen;
}
}
return str.substring(maxindex, maxindex+maxlen-1);
}
方法三:
/**时间复杂度o(n)
* 120135435
* @param str
* @return
*/
private static String noRepeatSubString2(String str){
//记录数字出现的位置
int visit[] = new int[10];
//记录到达i的最大子串的长度
int dp[] = new int[str.length()];
int last_start = 0;
int maxlen=0,maxindex=0;
for(int i=0;i<10;i++){
visit[i] = -1;
}
for(int i=0;i<str.length();i++){
dp[i] = 0;
}
visit[str.charAt(0)-'0'] = 0;
dp[0] = 1;
for(int i=1;i<str.length();i++){
int tmp = str.charAt(i)-'0';
if(visit[tmp]==-1){
dp[i] = dp[i-1]+1;
visit[tmp]=i;
}else{
if(last_start<=visit[tmp]){
last_start = visit[tmp]+1;
dp[i] = i-visit[tmp];
visit[tmp] = i;
}else{
dp[i] = dp[i-1]+1;
visit[tmp] = i;
}
}
if(dp[i]>maxlen){
maxlen = dp[i];
maxindex = i+1-maxlen;
}
}
return str.substring(maxindex, maxlen+maxindex-1);
}
改进方法三:
/**
* noRepeatSubString2的优化
* @param str
* @return
*/
private static String noRepeatSubString3(String str){
int visit[] = new int[10];
//记录到达i的最大子串的长度
int count = 1;
int last_start = 0;
int maxlen=0,maxindex=0;
for(int i=0;i<10;i++){
visit[i] = -1;
}
visit[str.charAt(0)-'0'] = 0;
for(int i=1;i<str.length();i++){
int tmp = str.charAt(i)-'0';
if(visit[tmp]==-1){
count++;
visit[tmp]=i;
}else{
if(last_start<=visit[tmp]){
last_start = visit[tmp]+1;
count = i-visit[tmp];
visit[tmp] = i;
}
}
if(count>maxlen){
maxlen = count;
maxindex = i+1-maxlen;
}
}
return str.substring(maxindex, maxlen+maxindex-1);
}