查找字符串中重叠和非重叠子串的数量

时间:2013-07-05 19:47:31

标签: python python-2.7

PS:这不是How to find the overlap between 2 sequences, and return it

的副本

[虽然如果可以应用于以下问题我请求上述方法的解决方案]

问:虽然我做对了,但它仍然不是一个可扩展的解决方案,绝对没有优化(得分低)。阅读以下问题描述,并提供更好的解决方案。

问题:

为简单起见,我们要求前缀和后缀非空并且比整个字符串S短。字符串S的边框是任何前缀和后缀的字符串。例如,"cut"是字符串"cutletcut"的边框,字符串"barbararhubarb"有两个边框:"b""barb"

class Solution { public int solution(String S); }

给定由S个字符组成的字符串N,返回其最长边框的长度,该边框在给定字符串中至少有三次非重叠出现。如果S中没有此类边框,则该函数应返回0.

例如,

  • 如果S = "barbararhubarb"该函数应返回1,如上所述;
  • 如果S = "ababab"该函数应返回2,则"ab""abab"都是S的边界,但只有"ab"有三个S = "baaab"非重叠事件;
  • 如果0该函数应返回"b",因为它的唯一边框N只出现两次。

假设:

  • [0..1,000,000]S;
  • 范围内的整数
  • 字符串a−z仅包含小写字母(O(N))。

复杂度:

  • 预计最坏情况时间复杂度为O(N);
  • 预期的最坏情况空间复杂度为def solution(S): S = S.lower() presuf = [] f = l = str() rank = [] wordlen = len(S) for i, j in enumerate(S): y = -i-1 f += S[i] l = S[y] + l if f==l and f != S: #print f,l new=S[i+1:-i-1] mindex = new.find(f) if mindex != -1: mid = f #new[mindex] #print mid else: mid = None presuf.append((f,mid,l,(i,y))) #print presuf for i,j,k,o in presuf: if o[0]<wordlen+o[-1]: #non overlapping if i==j: rank.append(len(i)) else: rank.append(0) if len(rank)==0: return 0 else: return max(rank) (不计算输入参数所需的存储空间)。

{{1}}

我的解决方案时间复杂度为:O(N 2)或O(N 4) 非常感谢。

5 个答案:

答案 0 :(得分:1)

我的解决方案是Rabin-Karp和Knuth-Morris-Pratt算法的结合。 http://codility.com/cert/view/certB6J4FV-W89WX4ZABTDRVAG6/details

答案 1 :(得分:0)

我有一个(Java)解决方案执行O(N)或O(N ** 3),总体上得到90/100,但我无法弄清楚如何通过2个不同的测试用例:

almost_all_same_letters aaaaa ... aa ?? aaaa ?? .... aaaaaaa 2.150 s。超时错误 运行时间:> 2.15秒,时间限制:1.20秒

same_letters_on_both_ends 2.120 s。超时错误 运行时间:> 2.12秒,时间限制:1.24秒

编辑:Nailed it! 现在我有一个在O(N)中执行的解决方案,并通过了100/100结果的所有检查:) 我不知道Codility,但它是一个很好的工具!

答案 2 :(得分:0)

我有一个带后缀数组的解决方案(实际上有用于在线性时间内构建SA和LCP的算法或比这更差的东西,但肯定不是二次的)。

仍然不确定我是否可以不使用RMQ(使用SegmentTree的O(log n))我无法通过我自己的情况并且看起来相当复杂,但是使用RMQ它可以(不提及使用for循环的方法而不是RMQ,无论如何都会使它成为二次方。)

解决方案执行速度非常快,并且通过我已经设法制作的各种特权来传递我的21个测试用例,但在某些情况下仍然失败。不确定这有助于你或者让你知道如何处理这个问题,但我确信像@Vicenco这样天真的解决方案在他的一些评论中说,不能让你比Silver好。

修改 设法解决所有问题,但仍然缓慢。我不得不强制执行一些条件,但不得不增加复杂性,仍然不确定如何优化它。将及时向大家发布。祝你好运!

答案 3 :(得分:0)

protected int calcBorder(String input) {
    if (null != input) {
        int mean = (input.length() / 3);
        while (mean >= 1) {
            if (input.substring(0, mean).equals(
                    input.substring(input.length() - mean))) {
                String reference = input.substring(0, mean);
                String temp = input
                        .substring(mean, (input.length() - mean));
                int startIndex = 0;
                int endIndex = mean;
                int count = 2;
                while (endIndex <= temp.length()) {
                    if (reference.equals(temp.substring(startIndex,
                            endIndex))) {
                        count++;
                        if (count >= 3) {
                            return reference.length();
                        }
                    }
                    startIndex++;
                    endIndex++;
                }
            }
            mean--;
        }
    }
    return 0;
}

答案 4 :(得分:0)

Z-Algorithm将是一个很好的解决方案。