Java编程任务效率

Java编程任务效率,java,time-complexity,performance,Java,Time Complexity,Performance,我正在努力学习编写更高效的代码。你们这些天才开发人员有没有可能帮助我,让我知道我的代码哪里出了问题?我怎样才能使它更有效率 我刚刚在Codility.com上完成了一项任务,并且通过了所有测试,但是当传入较大的字符串时,我的代码效率不够 任务说明: 字符串S的前缀是S的任何前导连续部分。对于 例如,“c”和“cod”是字符串“codility”的前缀。对于 简单来说,我们要求前缀为非空。前缀的乘积 字符串S的P是P的出现次数乘以 P的长度。更精确地说,如果前缀P由K个字符和 P在S中正好出现T次

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

我刚刚在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

“阿巴巴”,其乘积等于6*1=6

“阿巴巴巴”,其乘积等于7*1=7

最长前缀与原始字符串相同。目标是选择这样一个前缀,使产品的价值最大化。在上面的例子中,最大乘积是10

在这个问题中,我们只考虑由小写英文字母(a z)组成的字符串。

写一个函数

class Solution { public int solution(String S); }
给定由N个字符组成的字符串S,返回给定字符串的任何前缀的最大乘积。如果产品大于100000000,函数应返回100000000

例如,对于字符串:

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

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

假设:

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

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

复杂性:

期望最坏情况时间复杂度为O(N)

预计最坏情况下的空间复杂度为O(N)(不计算输入参数所需的存储)

以下是我失败的结果:

简单态射a->a?a 2.150秒。超时错误运行时间:>2.15秒。 大随机字符串循环+随机字符串1.180秒。超时错误 运行时间:>1.18秒

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

单字母带一些微调2.170秒。超时错误运行时间:>2.17秒

相同的\u小\u图案\u与\u小\u调整2.160秒。运行时超时错误 时间:>2.16秒

相同的大图案和小图案调整4.660秒。运行时超时错误 时间:>4.66秒

小图案,在一个位置上调整4.700秒。运行时超时错误 时间:>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;
    }
}
公共类测试{
公共静态void main(字符串[]args){
long startTime=System.nanoTime();
System.out.println(“解决方案:”+解决方案(“阿巴巴”);
long-endTime=System.nanoTime();
长持续时间=结束时间-开始时间;
System.out.println(“持续时间:+持续时间/1000000.0+秒”);
}
公共静态int解决方案(字符串S){
int solution=0,N=S.length();
字符串P;
对于(int K=1;K解){
溶液=TMP溶液;
}
}
回流液;
}
公共静态整数计算器(字符串P、字符串S){
int T=0,indexOfStart=0;
while(indexOfStart>-1){
T++;
indexOfStart=S.indexOf(P,indexOfStart+1);
}
返回T;
}
}

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

我还建议阅读有关Z算法的内容:

还有KMP算法:

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


我需要开始思考我的算法的方式是,遍历某个对象几次,以获得最终结果是可以的。这样做比将循环嵌套在循环中要好得多。

这里有一些提示:@afk5min Nice,我想知道你是事先知道的还是用谷歌搜索的?我最近听了一个名为“后缀结构”的讲座,内容是关于优化字符串中各种操作的占用内存的结构:P这种知识让我很震惊。@AFK5分钟谢谢,伙计,我已经通读了它们,我只是想知道如何在Java中使用它们作为找到解决方案的另一种方式