Java简单应用程序复杂性

时间:2017-03-27 09:01:50

标签: java time-complexity space-complexity

我不得不为面试解决问题,而且我不明白。 问题是,对于像“我们喜欢徒步旅行”这样的字符串来反转这样的字符串:“ew ekil gnikih”,这意味着,要爆炸字符串,如:str.split(“”),然后,每个单词反转和添加到新字符串。

问题出在问题的最后,因为问了一些关于复杂性的事情,比如: “ - 预期的最坏情况时间复杂度是O(N)”    - 预期的恶劣空间复杂度是O(N)(不计算输入参数所需的存储空间)

我解决了这个问题:

public static String solution(String S){

    if(S.length()>1 && S.length()<200000){

        String toReturn = "";

        String[] splitted = null;
        if(S.contains(" ")){
            splitted = S.split(" ");
        }
        else{
            splitted = new String[]{S};
        }

        for(int i=0;i<=splitted.length-1;i++){
            String wordToChange = splitted[i];
            String reversedWord = "";
            for(int j=wordToChange.length()-1;j>=0;j--)
                reversedWord+=wordToChange.charAt(j);

            toReturn+=" " + reversedWord;

        }

        return toReturn.trim();

    }
    return null;
}

我应该如何处理复杂性请求? 谢谢!

2 个答案:

答案 0 :(得分:2)

关于时间复杂性:

最坏情况O(N)意味着你应该有一个最糟糕的情况,你计算N迭代以获得结果,在你的情况下你将String拆分成一个字符串数组[操作可能需要O (N),但它取决于方法split()],然后对于数组中的每个String,从String的结尾开始并反转字符。 所以你最坏的情况是O(N)+ O(N)...... = O(N)

关于空间复杂性:

每个String都是一个对象,你在内存中为你创建的每个String保留空间,这里有一个字符串数组,意味着你为从原始字符串中拆分的每个单词或字母创建一个对象。 你最糟糕的情况是像#34;我是一个&#34;在其中为每个字符创建一个字符串 - &gt; O(N)

希望这能澄清你的怀疑

答案 1 :(得分:0)

我认为这至少不是时间复杂性的正确答案。

在我看来,字符串的拆分很可能是O(n)的复杂性。它只会增加下一个复杂性,因此我们可以忘记它。

现在,您正在创建一个空String并在每个String的顶部连接一个char。在这里,您假设此操作与将数值插入数组(O(1))一样便宜。

在这种情况下,你应该假设,每次使用成员方法concat()创建一个新的String。如果您有机会查看String.concat(String)的实现,您会看到此方法正在创建另一个字符串长度为string1.length + string2.length并且正在复制string1和string2进去。所以这种方法本身就具有O(n)的复杂性。

因为你为一个n长度的单词连接n个字符,所以对于一个单词,它具有O(n *(n / 2))= O(n ^ 2)的复杂度。假设只有一个单词的最坏情况,你的复杂度等级为O(n ^ 2)。

我会同意代码的O(n)空间复杂度类。但这只是假设JVM的智能重用你未使用的空间。

您的代码应该可以运行,但我认为这个问题确实不是很好的代码。您可以使用StringBuilder或对char []进行直接操作来改进它。

StringBuilder是一个好主意,因为它的行为类似于Vector或ArrayList。我有一个比String更大的char []工作。如果超出容量(通过使用append()方法),它将创建一个更大的数组,类似于前一个后备数组的2倍。这可能只是O(nlogn)的时间复杂度。但是你可以通过初始化StringBuilder来调整它,其容量与初始String的大小相同。这意味着支持char []根本不会被复制,因为你不会超过它的容量。

以下是使用char []:

的示例
private static void reverseCharArray(char[] result, int start, int end) {
    int halfDifference = (end - start) / 2;
    for (int i = 0; i < halfDifference; i++) {
        char buffer = result[start + i];
        result[start + i] = result[end - i - 1];
        result[end - i - 1] = buffer;
    }
}    

public static String reverseWordInString(String string) {
    char[] stringAsCharArray = string.toCharArray();

    int indexStart = 0;
    for (int indexEnd = 0; indexEnd < stringAsCharArray.length; indexEnd++) {
        if (stringAsCharArray[indexEnd] != ' ') {
            continue;
        }
        StringOperations.reverseCharArray(stringAsCharArray, indexStart, indexEnd);
        indexStart = indexEnd + 1;
    }
    StringOperations.reverseCharArray(stringAsCharArray, indexStart, stringAsCharArray.length);

    return String.valueOf(stringAsCharArray);
}