文字の繰り返し最長の部分文字列いいえ:48の顔の質問
一つ、タイトル説明
文字列から文字を繰り返し含まれていない最長共通文字列を検索してください、私たちは最も長い部分文字列の長さを計算します。仮定文字列はの「」に「Z」の文字だけが含まれています。
例えば、文字の最長の部分文字列を除いた文字列「arabcacfr」は、4の長さを「ACFR」を繰り返しています。
第二に、問題分析
遭遇する問題は、最初の問題を分析し、アルゴリズムの使用は、分析の結果によって決定されます。
一般的に、私たちは、紙の上で基本的な状況のいくつかのリストを描画するために紙にペンを入れます。この質問の分析後の関係で見つけることができます。
定義された関数f(i)は:なし繰り返し文字の終わりに、i番目の文字でサブストリングの最大長。
i番目の文字が見られなかったの前に(1)、があります。F(I)= Fは、(i-1)+1を付けました
(2)は、i番目の文字の前に現れ、そして最後の文字が現れるの場所を確認した場合距離d
- Dもし<= F(I-1)、F(I)= dが存在します。
- D> F(I-1)の場合、F(I)= F(I-1)+1があります。
トラバースは、最初の文字から始まり、F(I-1)及びf(i)を表すために2つのint変数preLength curLengthを定義し、そして最後に現れる26文字を格納するための長さPOS 26の配列を作成することができ上記の説明を解決するために、位置。
第三に、この問題は解決され
public int maxLength(String str) {
if(str==null || str.length()<=0) {
return 0;
}
// 即f(i-1)
int preLength=0;
// 即f(i)
int curLength;
int maxLength=0;
// 用于存放字母上次出现的位置
int[] pos= new int[26];
Arrays.fill(pos, 0);
for(int i=0;i<str.length();i++) {
int letterNumber = str.charAt(i)-'a';
if(pos[letterNumber]<0 || i-pos[letterNumber]>preLength) {
curLength=preLength + 1;
} else {
curLength=i-pos[letterNumber];
}
pos[letterNumber]=i;
if(curLength>maxLength) {
maxLength=curLength;
}
preLength=curLength;
}
return maxLength;
}