找出最佳解决方案的数据结构

用户名

该问题是正在进行的竞赛的一部分,我已经解决了该问题数据集的75%,但25%给了我TLE。我问为什么它给TLE我一个我确定我的复杂性是O(n*n)

问题:

由N个小写英文字母组成的字符串S。我们已经准备组成的列表L all non empty substrings of the string S

现在他问你Q问题。对于第一个问题,您需要计算从列表L中完全选择Ki个相等字符串的方法的数量。

例如:

    String  = ababa
L = {"a", "b", "a", "b", "a", "ab", "ba", "ab", "ba", "aba", "bab", "aba", "abab", "baba", "ababa"}.
k1 = 2: There are seven ways to choose two equal strings ("a", "a"), ("a", "a"), ("a", "a"), ("b", "b"), ("ab", "ab"), ("ba", "ba"), ("aba", "aba").
k2 = 1: We can choose any string from L (15 ways).
k3 = 3: There is one way to choose three equal strings - ("a", "a", "a").
k4 = 4: There are no four equal strings in L .

问题链接


我的方法

我正在进行IT的TRIE并计算和数组F [i],其中F [i]表示我等于发生字符串的次数。我的TRIE:

 static class Batman{

        int value;
        Batman[] next = new Batman[26];

        public Batman(int value){
            this.value = value;
            } 
 }

我的插入功能

 public static void  Insert(String S,int[] F , int start){

     Batman temp = Root;
     for(int i=start;i<S.length();i++){
         int index = S.charAt(i)-'a';

         if(temp.next[index]==null){
             temp.next[index] = new Batman(1);
             F[1]+=1;

         }else{
             temp.next[index].value+=1;
             int xx = temp.next[index].value;
             F[xx-1]-=1;
             F[xx]+=1;

            // Calculating The Frequency of I equal Strings
         }
         temp = temp.next[index];
     }

 }

我的主要功能

public static void main(String args[] ) throws  java.lang.Exception  {

Root = new Batman(0);
int n = in.nextInt();
int Q = in.nextInt();
String S = in.next();
int[] F = new int[n+1];

for(int i=0;i<n;i++)
    Insert(S,F,i);


long[] ans = new long[n+1];


for(int i=1;i<=n;i++){
    for(int j=i;j<=n;j++){
        ans[i]+= F[j]*C[j][i];  // C[n][k] is the Binomial Coffecient
        ans[i]%=mod;
    }
}


 while(Q>0){
     Q--;
    int cc = in.nextInt();
    long o =0;
    if(cc<=n) o=ans[cc];
     System.out.println(o+" "+S.length());
 }
}



为什么当时间复杂度为O(N * N)且String的长度为N <= 5000时,我的方法会授予TLE。请帮我工作代码

范·邓

该程序获得TLE的原因之一(请注意,时间限制为1秒):

每次创建Batman对象时,都会创建一个长度为[26]的数组,这等效于添加一个n = 26的循环。

因此,您的时间复杂度为26 * 5000 * 5000 = 650000000 = 6.5 * 10 ^ 8个操作,从理论上讲,如果CPU速度为每秒10 ^ 9个操作,它仍然可以满足时间限制,但是请记住,大量的计算工作在此之后,因此,这应该是原因。

为了解决这个问题,我使用了Z算法并被接受:链接

实际的代码非常复杂,所以想法是,您有一个table count[i][j],它是与子字符串(i,j)匹配的子字符串的数量。使用Z算法,时间复杂度为O(n ^ 2)。

对于每个字符串s

        int n = in.nextInt();
        int q = in.nextInt();
        String s = in.next();
        int[][] cur = new int[n][];
        int[][] count = new int[n][n];
        int[] length = new int[n];
        for (int i = 0; i < n; i++) {
            cur[i] = Z(s.substring(i).toCharArray());//Applying Z algorithm
            for (int j = 1; j < cur[i].length; j++) {
                if (cur[i][j] > length[j + i]) {
                    for (int k = i + length[j + i]; k < i + cur[i][j]; k++) {
                        count[i][k]++;
                    }
                    length[j + i] = cur[i][j];
                }

            }
        }
        int[] F = new int[n + 1];
        for(int i = 0; i < n; i++){
            for(int j = i; j < n; j++){
                int v = count[i][j] + (length[i] < (j - i + 1) ? 1 : 0);
                F[v]++;
            }
        }

Z算法:

public static int[] Z(char[] s) {
    int[] z = new int[s.length];
    int n = s.length;
    int L = 0, R = 0;
    for (int i = 1; i < n; i++) {
        if (i > R) {
            L = R = i;
            while (R < n && s[R - L] == s[R])
                R++;

            z[i] = R - L;

            R--;
        } else {
            int k = i - L;
            if (z[k] < R - i + 1) {
                z[i] = z[k];
            } else {
                L = i;
                while (R < n && s[R - L] == s[R])
                    R++;
                z[i] = R - L;
                R--;
            }
        }
    }
    return z;
}

实际代码:http//ideone.com/5GYWeS

说明

首先,我们有一个数组长度,length[i]是与从索引开始的字符串匹配的最长子字符串i

对于每个索引i,计算Z函数后,我们看到if cur[i][j] > length[j + i],这意味着存在一个比在index处匹配的先前子字符串长的子字符串j + i,并且我们没有在结果中对它们进行计数,因此我们需要对它们进行计数。

因此,即使有3个嵌套的for循环,但每个子字符串仅被计数一次,因此整个时间复杂度为O(n ^ 2)

        for (int j = 1; j < cur[i].length; j++) {
            if (cur[i][j] > length[j + i]) {
                for (int k = i + length[j + i]; k < i + cur[i][j]; k++) {
                    count[i][k]++;
                }
                length[j + i] = cur[i][j];
            }          
        }

对于下循环,我们注意到,如果子字符串(i,j)length[i] >= length of substring (i,j)有匹配项,但是如果没有匹配项,则需要加1来计数子字符串(i,j),因为该子字符串是唯一的。

        for(int j = i; j < n; j++){
            int v = count[i][j] + (length[i] < (j - i + 1) ? 1 : 0);
            F[v]++;
        }

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

算法设计手册中有关数据结构的最佳解决方案

来自分类Dev

过滤R数据帧以获取最佳解决方案

来自分类Dev

“名人”算法的最佳解决方案

来自分类Dev

WebSocket:后端的最佳解决方案

来自分类Dev

尝试最佳解决方案?

来自分类Dev

字谜检查的最佳解决方案?

来自分类Dev

背包最佳解决方案(蛮力)

来自分类Dev

寻找最佳解决方案

来自分类Dev

忽略maxLength的最佳解决方案

来自分类Dev

级联IF语句-最佳解决方案

来自分类Dev

ASP.NET MVC n层体系结构-最佳解决方案

来自分类Dev

XSRF / CSRF安全REST呼叫的最佳解决方案?

来自分类Dev

jQuery“窗帘”功能-最佳解决方案?

来自分类Dev

托管搜寻器的最佳解决方案?

来自分类Dev

网页中水平对齐的最佳解决方案?

来自分类Dev

最大单笔销售利润算法的最佳解决方案

来自分类Dev

使用nloptr查找N个最佳解决方案

来自分类Dev

物体可以被处置多次-最佳解决方案

来自分类Dev

爱丽丝·鲍勃硬币的最佳解决方案

来自分类Dev

在iCloud上保存游戏进度:最佳解决方案?

来自分类Dev

在HaxeFlixel中编码资产的最佳解决方案

来自分类Dev

多线程网络刮板的最佳解决方案?

来自分类Dev

插入时需要mysql事件的最佳解决方案?

来自分类Dev

Android REST客户端:最佳解决方案?

来自分类Dev

iOS 9解析JSON的最佳解决方案

来自分类Dev

控制访问StrongLoop中模型的最佳解决方案

来自分类Dev

解锁网络音频的最佳解决方案

来自分类Dev

流程树问题的最佳解决方案

来自分类Dev

在Elasticsearch中更改设置的最佳解决方案