以下は、codility というコーディング インタビュー サイトからのデモの質問です。
文字列 S の接頭辞は、S の先頭の連続部分です。たとえば、「c」と「cod」は、文字列「codility」の接頭辞です。簡単にするために、プレフィックスは空ではない必要があります。
文字列 S のプレフィックス P の積は、P の出現回数に P の長さを掛けたものです。より正確には、プレフィックス P が K 文字で構成され、P が S 内でちょうど T 回出現する場合、積は K * T に等しくなります。
たとえば、S = "abababa" には次の接頭辞があります。
- 「a」、その積は 1 * 4 = 4 に等しい、
- 「ab」、その積は 2 * 3 = 6 に等しい、
- 「aba」、その積は 3 * 3 = 9 に等しく、
- 「abab」、その積は 4 * 2 = 8 に等しい、
- その積が 5 * 2 = 10 に等しい「アババ」、
- 「ababab」、その積は 6 * 1 = 6 に等しく、
- 「アババ」、その積は 7 * 1 = 7 です。
最長のプレフィックスは元の文字列と同じです。目標は、製品の価値を最大化するような接頭辞を選択することです。上記の例では、最大積は 10 です。
以下は、O(N ^ 2)時間を必要とするJavaでの私の貧弱なソリューションです。O(N)でこれを行うことは明らかに可能です。Kadanesアルゴリズムを考えていました。しかし、実行中の最大値を見つけることができるように、各ステップでいくつかの情報をエンコードできる方法は考えられません。このための O(N) アルゴリズムを考えられる人はいますか?
import java.util.HashMap;
class Solution {
public int solution(String S) {
int N = S.length();
if(N<1 || N>300000){
System.out.println("Invalid length");
return(-1);
}
HashMap<String,Integer> prefixes = new HashMap<String,Integer>();
for(int i=0; i<N; i++){
String keystr = "";
for(int j=i; j>=0; j--) {
keystr += S.charAt(j);
if(!prefixes.containsKey(keystr))
prefixes.put(keystr,keystr.length());
else{
int newval = prefixes.get(keystr)+keystr.length();
if(newval > 1000000000)return 1000000000;
prefixes.put(keystr,newval);
}
}
}
int maax1 = 0;
for(int val : prefixes.values())
if(val>maax1)
maax1 = val;
return maax1;
}
}