Java编程任务效率



我正在努力学习编写更高效的代码。你们这些天才开发人员有没有可能帮助我,让我知道我的代码哪里出了问题?如何提高效率?

我刚刚在Codility.com上完成了一项任务,我通过了所有的测试,但当较大的字符串传入时,我的代码效率不够。

任务描述:

字符串S的前缀是S的任何前导连续部分。对于例如,"c"one_answers"cod"是字符串"codility"的前缀。对于简单地说,我们要求前缀不为空。前缀的乘积字符串S的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的情况下,返回给定字符串的任何前缀的最大乘积。如果乘积大于1000000000,函数应返回1000000000。

例如,对于字符串:

S="abababa"函数应返回10,如上所述,

S="aaa"函数应返回4,作为前缀的乘积"aa"是最大的。

假设:

N是[1..300000]范围内的整数;

字符串S仅由小写字母(a-z)组成。

复杂性:

预期最坏情况下的时间复杂度为O(N);

预期最坏情况下的空间复杂度为O(N)(不包括输入自变量所需的存储)。

以下是我失败的结果:

易同构a->a?a 2.150秒超时错误运行时间:>2.15秒。large_random_string循环+随机字符串1.180秒超时错误运行时间:>1.18秒。

大型循环大型循环测试2.170秒超时错误运行时间:>2.17秒。

single_letter_with_some_tweaks 2.170秒超时错误运行时间:>2.17秒

same_mall_pattern_with_small_tweaks 2.160 s。运行超时错误时间:>2.16秒

same_big_pattern_with_small_tweaks 4.660 s。运行超时错误时间:>4.66秒

small_pattern_with_tweaks_in_one_place 4.700 s。运行超时错误时间:>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;
    }
}

经过一番搜索,我最终找到了一些解决方案。感谢@afk5min的建议。

我还建议阅读有关Z-Algorithms的文章:http://codeforces.com/blog/entry/3107

以及KMP算法:http://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm

我认为我需要学习的提高效率的主要方法是不要安于现状。如果代码进入一个循环,然后进入另一个循环时,它会突然消耗更多的时间,并且在扩展时效率低下。

我需要开始思考我的算法的方法是,可以遍历一些东西几次,以获得最终结果。这样做比把环套在环里要好得多。

最新更新