我正在努力学习编写更高效的代码。有些天才开发人员可以帮助我,让我知道我的代码出错了吗?我怎样才能提高效率呢?
我刚刚在Codility.com上完成了一项任务,并且我通过了所有测试,但是当传入更大的字符串时,我的代码效率不高。
任务说明:
字符串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。
在这个问题中,我们只考虑由小写英文字母(a-z)组成的字符串。
写一个函数
class Solution { public int solution(String S); }
给定由N个字符组成的字符串S,返回给定字符串的任何前缀的最大乘积。如果产品大于1,000,000,000,则该函数应返回1,000,000,000。
例如,对于字符串:
S =“abababa”该函数应返回10,如上所述,
S =“aaa”函数应返回4,作为前缀的乘积 “aa”是最大的。
假设:
N是[1..300,000]范围内的整数;
字符串S仅由小写字母(a-z)组成。
复杂度:
预期的最坏情况时间复杂度为O(N);
预期的最坏情况空间复杂度为O(N)(不计算输入参数所需的存储空间)。
以下是我失败的结果:
easy_morphism a - > a?a 2.150 s。 TIMEOUT ERROR运行时间:> 2.15秒。 large_random_string cyclic + random string 1.180 s。超时错误 运行时间:> 1.18秒
large_cyclic大型循环测试2.170 s。 TIMEOUT ERROR运行时间:> 2.17秒
single_letter_with_some_tweaks 2.170 s。 TIMEOUT ERROR运行时间:> 2.17秒
same_small_pattern_with_small_tweaks 2.160 s。 TIMEOUT ERROR正在运行 时间:> 2.16秒
same_big_pattern_with_small_tweaks 4.660 s。 TIMEOUT ERROR正在运行 时间:> 4.66秒
small_pattern_with_tweaks_in_one_place 4.700秒。 TIMEOUT ERROR正在运行 时间:> 4.70秒
任何帮助或提示都会很方便!
public class test {
public static void main(String[] args) {
long startTime = System.nanoTime();
System.out.println("solution: " + solution("abababa"));
long endTime = System.nanoTime();
long duration = endTime - startTime;
System.out.println("duration: " + duration/1000000.0 + " seconds");
}
public static int solution(String S) {
int solution = 0, N = S.length();
String P;
for (int K = 1; K <= N; K++) {
P = S.substring(0, K);
int T = calculateT(P, S);
int tmpSolution = K * T;
if (tmpSolution > solution) {
solution = tmpSolution;
}
}
return solution;
}
public static int calculateT(String P, String S) {
int T = 0, indexOfStart = 0;
while (indexOfStart > -1) {
T++;
indexOfStart = S.indexOf(P, indexOfStart+1);
}
return T;
}
}
答案 0 :(得分:3)
经过一番搜索,我最终遇到了一些解决方案。感谢@ afk5min的建议。
我还建议阅读Z-Algorithms: http://codeforces.com/blog/entry/3107
以及KMP算法:http://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm
我认为我需要学习的与效率有关的主要事情不是嵌套循环。如果代码进入循环然后进入另一个循环,它会突然消耗更多的时间并且变得无法进行扩展。
我需要开始考虑我的算法的方法是,可以遍历几次,以获得最终结果。这样做比在循环中嵌套循环要好得多。