运行时反转字符串中的单词

时间:2014-11-21 19:26:10

标签: algorithm runtime big-o

让我们说我们的任务是扭转字符串中的单词。

所以,如果我们有:

玛丽有一只小羊羔

我们得到:

yram dah a elttil bmal


实施的算法如下:

string wordsToSplit = "Mary had a little lamb";

string[] words = wordsToSplit.split(" ");
string wordsReversed = "";

foreach( string word in words ) 
{
      string reversedWord = "";
      foreach( char letter in word ){
          reversedWord = letter + reversedWord;
      }
      wordsReversed += " " + reversedWord;
}

这个伪代码应该可行。但是这个特定算法的运行时间是多少?我以为它会是O(n ^ 2),其中N是字符串中的单词数。但这似乎不对......

有些东西告诉我这实际上是O(N)* O(M),其中' N'是单词的数量和' M'是每个单词中的字符数。所以在最坏的情况下,这可能是O(n ^ 2),如果我们有类似的东西,那就是" a b c d e f g h i j k l m n o p" ...

你怎么看?这让我烦恼......

2 个答案:

答案 0 :(得分:2)

实际时间复杂度取决于您的语言如何实现字符串连接。例如,在Java中,循环中的天真字符串连接将花费O(N * M)时间,其中N是总字符串长度,M是要追加的字符串数。

在合理的连接算法中(例如使用Java的StringBuilder;参见Dynamic Arrays),内部使用自增长缓冲区,以保证一系列连接的线性时间。< / p>

无论如何,在你的情况下,不需要动态缓冲区 - 你事先知道你构建的字符串的长度。您甚至可以将输入视为char数组,并就地进行工作。

答案 1 :(得分:0)

在你的算法中:

  • split在输入字符串的长度上具有线性复杂性

  • 假设通过

    string wordsReversed;
    

    你的意思是

    string wordsReversed = "";
    

    wordsReversed.join(" ", reversedWord);
    

    你的意思是

    wordsReversed += " " + reversedWord;
    

    然后外部foreach循环的主体在word的长度上具有线性复杂性,因为内部foreach循环和reversedWordwordsReversed的串联word的长度具有线性复杂性。

  • 最后,word中所有words s的长度总和是初始输入字符串的长度

因此,你的总复杂度应该是O(n)。

此外,由于上述原因,“a b c d e f g h i j k l m n o p”不是这种算法的最坏情况,尽管在这种情况下算法确实会有些低效。