以下是来自名为 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,
- "ababa",其乘积等于 5 * 2 = 10,
- “ababab”,其乘积等于 6 * 1 = 6,
- “abababa”,其乘积等于 7 * 1 = 7。
最长前缀与原始字符串相同。目标是选择使产品价值最大化的前缀。在上面的示例中,最大乘积为 10。
以下是我在 Java 中需要 O(N^2) 时间的糟糕解决方案。显然可以在 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;
}
}