【问题标题】:Solution critique: reversing words in a sentence解决方案批评:在句子中颠倒单词
【发布时间】:2014-11-24 09:53:14
【问题描述】:

我参加了一次技术面试,被问到以下问题:

编写一个函数,接收一个句子并以相反的顺序返回包含单词的句子(即“hello world”变为“world hello”)。

这是我在 Java 中给出的解决方案:

/** Takes a sentence as an input and returns the sentence with the words in
 *  reversed order. */
private static String reverseSentence(String sentence) {
    String[] words = sentence.split("\\s+");
    String reversedString = "";
    for (int k = words.length - 1; k >= 0; k -= 1) {
        reversedString += " " + words[k];
    }
    return reversedString.substring(1);
}

我开始思考必须有比这更有效的方法来解决这个问题。如果这个解决方案被证明是最好的并且没有比它更高效/更优雅的解决方案,我认为在*公司的技术面试中不会问这个问题。

谁能想到更好的方法来做到这一点?

【问题讨论】:

  • 是的。使用StringBuilder 而不是String reversedString。字符串连接(尤其是在循环中)效率不高。
  • 有一个Collections.reverse 方法:docs.oracle.com/javase/7/docs/api/java/util/… 你应该可以使用它。
  • 如果你好世界呢?如果我的字符串只包含一个空格怎么办?虽然我不是那里的面试官,但他们肯定会寻找异常/边缘案例处理。
  • 是的,但是当你倒车时你会回来 \t 吗?
  • 在深入研究答案之前总是询问用例。通常在速度和可维护性之间进行权衡。

标签: java algorithm


【解决方案1】:

以下是连接句子元素的更好方法:What's the most elegant way to concatenate a list of values with delimiter in Java?

此外,sentence.split("\\s+") 仅在输入干净时才有效(人们确实会打错字)。还有一些问题应该如何处理标点符号。 World! Hello, 看起来确实很奇怪。

【讨论】:

  • String.join 也是一个不错的选择。即使效率可能不那么高,它也是“开箱即用”的。
【解决方案2】:

除了注释,要使用更高效的数据结构(StringBuilder)来创建字符串,我认为你可以做的不多。反转数组的时间复杂度是 n/2 (How do I reverse an int array in Java?) 但之后您仍然需要连接所有项目,这应该是 n - 因为您要立即连接它们,所以您从 @987654324 下来@ 只给n

【讨论】:

    【解决方案3】:

    通过交换引用(0 和长度为 1 等)反转数组后,您就可以

    String reversedSentence = String.join( " ", words );
    

    但我认为最好避免使用 String 数组。

    String s = "the quick brown fox";
    StringBuilder sb = new StringBuilder();
    int p = s.length();
    int np = -1;
    while( (np = s.lastIndexOf( " ", p-1 )) != -1 ){
        sb.append( s.substring( np + 1, p ) ).append( " " );
        p = np; 
    }
    sb.append( s.substring( 0, p ) );
    System.out.println( sb.toString() );
    

    这假定输入字符串已正确“规范化”。

    【讨论】:

      【解决方案4】:

      有时这个问题被问到一个约束,要求它在不使用任何额外内存的情况下完成。

      这个修改后的问题的一个答案是:

      1. 先反转句子中的每个单词(“Hello World”->“olleH dlroW”)
      2. 然后倒转整个句子(“olleH dlroW”->“World Hello”)

      【讨论】: