【问题标题】:Algorithm for finding first repeated substring of length k查找长度为 k 的第一个重复子串的算法
【发布时间】:2011-08-25 16:43:57
【问题描述】:

我有一个作业要做,我需要帮助。我应该编写一个程序来查找在字符串中至少重复两次的长度为 k 的第一个子字符串。

例如,在字符串“banana”中有两个长度为 2 的重复子字符串:“an”、“na”。在这种情况下,答案是“an”,因为它出现的时间早于“na”

请注意,简单的 O(n^2) 算法没有用,因为程序的执行时间有时间限制,所以我猜应该是线性时间。

还有一个提示:使用哈希表。

我不想要代码。我只是想让你给我一个线索,因为我不知道如何使用哈希表来做到这一点。我也应该使用特定的数据结构吗?

【问题讨论】:

  • 您使用哪种语言编码?

标签: algorithm string data-structures hash substring


【解决方案1】:

遍历字符串的字符索引 (0, 1, 2, ...),直到并包括倒数第二个字符的索引(即直到 strlen(str) - 2)。对于每次迭代,请执行以下操作...

提取从字符索引开始的 2 字符子字符串。

检查您的哈希表是否包含 2 字符子字符串。如果是这样,你就有答案了。

将每个 2 字符的子字符串插入哈希表中。

这很容易修改以处理长度为 k 的子串。

【讨论】:

  • 计算哈希函数是 O(k) 并且通过迭代字符串的字符,算法的执行时间将是 O(nk) 或 O(n^2),这是很多时间!还是谢谢你的回复
  • O(nk) 不是 O(n^2) - k 与正在搜索的字符串的长度无关。不过,我当然可以看到你的论点来自哪里。我会断言,没有(明显)更好的方法可以用哈希表来做到这一点。
  • 1
  • @omid: k 在你的任务中是一个常数,也就是说,它不依赖于字符串长度n。所以,你不能写k = n - c,因为n 可以改变并且复杂性将保持不变。例如,如果计算长度为 10 的字符串需要 100 毫秒,则计算 20 个字符的字符串将需要 200 毫秒 (n * 2) 而不是 400 毫秒 ((n * 2)^2)。所以,k 不会改变时间复杂度。尽管如此,值得一提的是,在一些任务中,子字符串长度k可能会影响时间复杂度。
  • ffriend 和 Will A:你是对的。你想说:nk 不是 theta(n^2) 没错,但它是 O(n^2)。然而,在我的情况下,重要的是 theta 不是 O
【解决方案2】:

将 Will A 的算法与 rolling hash 结合起来得到一个线性时间算法。

【讨论】:

  • 另外,omid,你是对的:任何 O(n k) 的函数也是 O(n^2),因为 O(在 Knuth 的传统中)是上界。 ffriend 是对的,然而,对于小 k,n k 是对 n^2 的显着改进。
【解决方案3】:

您可以使用链接哈希映射。

public static String findRepeated(String s , int k){
    Map<String,Integer> map = new LinkedHashMap<String,Integer>();
    for(int i = 0 ; i < s.length() - k ; i ++){
        String temp = s.substring(i,i +k);
        if(!map.containsKey(temp)){
            map.put(temp, 1);
        }
        else{
            map.put(temp, map.get(temp) + 1);
        }
    }
    for(Map.Entry<String,Integer> entry : map.entrySet()){
        if(entry.getValue() > 1){
            return entry.getKey();
        }
    }
    return "no such value";
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-02
    • 2021-08-29
    • 2020-11-08
    • 2021-07-24
    • 2016-08-11
    • 1970-01-01
    • 2020-03-19
    • 2012-10-29
    相关资源
    最近更新 更多