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

Java 查找包含所有给定字符串的最小长度子字符串,java,algorithm,divide-and-conquer,Java,Algorithm,Divide And Conquer,给定一个大文档和一个由几个单词组成的简短模式 (如W1 W2 W3),找到包含所有单词的最短字符串 订单(例如,W2 foo bar dog W1 cat W3——是有效的模式) 我将“大文档”结构化为字符串列表。我相信我的解决方案是O(nlog(n)),但我不确定(我也不确定它是否正确)。有没有更快的办法?请注意,下面的代码是伪代码Java,因此显然不会编译,但我相信信息是清楚的: main(){ List<String> wordsToCheckFor; List

给定一个大文档和一个由几个单词组成的简短模式 (如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;
}
main(){
列出要检查的单词;
列出所有单词;
int-allWordsLength=allWords.length;
int minStringLength=位置无穷大;
列表minString;
//这里的想法是分而治之,我将首先
//检查整个字符串,然后检查整个字符串减去第一个字符串
//单词,然后整个字符串减去前两个单词,依此类推。。。
对于(int x=0;x
您的解决方案具有O(n^2)时间复杂度(在最坏的情况下,每个后缀都会被选中,每个检查都是O(n),因为List.contains方法具有线性时间复杂度)。此外,这是不正确的:答案并不总是后缀,它可以是任何子字符串

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

这至少是O(n*n)。您正在调用List.contains(即O(n))n次。这也不正确。如果模式位于字符串的开头,则它将不起作用。例如:
W1 W2 W3 a b c