查找包含所有给定字符串的最小长度子字符串

时间:2014-11-14 23:23:09

标签: java algorithm divide-and-conquer

  

给出一个大文档和一个由几个单词组成的简短模式   (例如,W1 W2 W3),找到包含所有单词的最短字符串   订单(例如,W2 foo bar dog W1 cat W3 - 是一种有效模式)

我将“大文档”构建为字符串列表。我相信我的解决方案是O(nlog(n)),但我不确定(我也不确定它是否正确)。有更快的方法吗?请注意,下面是伪编码的Java,所以显然不会编译,但我相信这个消息很明确:

main(){
    List<String> wordsToCheckFor;
    List<String> allWords;
    int allWordsLength = allWords.length;
    int minStringLength = POS_INFINITY;
    List<String> minString;

    //The idea here is to divide and conquer the string; I will first
    //check the entire string, then the entire string minus the first
    //word, then the entire string minus the first two words, and so on...

    for(int x = 0; x < allWordsLength; x++){
        if(checkString(allWords, wordsToCheckFor) && (allWords.length < minStringLength)){
            minString = allWords;
            minStringLength = allWords.length();
        }   
        allWords.remove(0);
    }

    System.out.println(minString);          
}


checkString(List<String> allWords, List<String> wordsToCheckFor){
    boolean good = true;
    foreach(String word : wordsToCheckFor){
        if(!allWords.contains(word))
            good = false;
    }
    return good;
}

1 个答案:

答案 0 :(得分:0)

您的解决方案具有O(n ^ 2)时间复杂度(在最坏的情况下,检查每个后缀,并且每个检查都是O(n),因为List.contains方法具有线性时间复杂度)。而且,它不正确:答案并不总是后缀,它可以是任何子字符串。

更有效的解决方案:逐字迭代文本并跟踪模式中每个单词的最后一次出现(例如,使用哈希表)。在每次迭代后更新答案(候选子字符串是从模式中的所有单词到当前位置的最小最后一次出现的子字符串)。该解决方案具有线性时间复杂度(假设模式中的字数是常数)。