我们不难找出字符串的所有子字符串,然后就可以判断每个子字符串中是否包含重复的字符。这种蛮力方法唯一的缺点就是效率。一个长度为n个字符串中有n方个子字符串,我们需要O的时间判断一个字符串中是否包含重复的字符,因此该解法的总时间效率是On的三次方。
接下来我们用动态规划算法来提高效率。首先定义函数f(i)表示以第i个字符为结尾的不包含重复字符的字符串的最长长度,我们从左到右逐一扫描字符中的每个字符,当我们计算以第i个字符为结尾的不包含重复字符的子字符串的最长长度为f(i),我们已经知道f(i-1)了。
如果第i个字符之前没有出现过,那么f(i)=f(i-1)+1。例如,在字符串 “arabcacfr”中,显然f(0) = 1,在计算f(1)时,下标为1的字符r之前没有出现过,因此f(1) =2,即f(1) = f(0)+1,到目前为止,最长的不含重复字符的子字符串是"ar"
如果第i个字符之前已经出现过,那情况就要复杂一点了。我们先
package question48_find_string_no_repeat;
/**
* @Classname Solution
* @Description TODO
* @Date 2020/3/29 0:00
* @Created by mmz
*/
public class Solution {
public static int findNoRepeate(String str){
if(str == ""||str==null||str.length()<=0){
return 0;
}
char[] chars = str.toCharArray();
int[] max = new int[str.length()];
max[0] = 1;
int curLength = 1 ;
boolean flag =false;
for(int i =1;i<chars.length;++i){
flag = false;
for(int j=0;j<i;++j){
if(chars[i]==chars[j]){
curLength= i-j;
if(curLength>max[i-1]){
curLength = max[i-1];
}
flag=true;
}
}
if(!flag){
curLength++;
}
if(max[i-1]<curLength){
max[i] = curLength;
}else{
max[i] = max[i-1];
}
}
int maxNum = 0;
for(int i=0;i<str.length();++i){
if(max[i]>maxNum){
maxNum = max[i];
}
}
return maxNum;
}
public static void main(String[] args) {
System.out.println(findNoRepeate("arabcacfr"));
}
}