我用o(n)时间复杂度和o(n)空间复杂度方法解决了相关问题如下;但受访者希望o(n)时间复杂度与恒定的空间复杂性。如何以恒定的空间复杂度解决它?
public static StringBuilder removeWhiteSpaces (String str){
if (str == null){
throw new IllegalArgumentException();
}
StringBuilder result = new StringBuilder();
for (int i = 0 ; i < str.length(); i++){
if (str.charAt(i) != ' '){
result.append(str.charAt(i));
}
}
return result;
}
答案 0 :(得分:1)
我不熟悉Java,但我确实记得String
是不可变的。当要剥离的字符串存储在String
内时,您所要求的是不可能的。这是因为我们无法修改输入,我们需要内存来存储结果。
但是,如果您可以将字符串存储在可变内存中(例如char[]
或StringBuilder
),则可以使用以下算法。保留两个索引r
和w
并将它们初始化为0.使用r
循环遍历字符串,为您读取的每个字符递增它。然后,如果该字符不是空格,请将其写入w
并递增它。
完成后丢弃字符串的最后r - w
个字符。
C:
中的示例void remove_whitespace(char* s) {
char* r = s;
char* w = s;
while (*r) {
if (!std::isspace(*r)) *w++ = *r;
++r;
}
*w = 0;
}
答案 1 :(得分:1)
有两种很好的方法可以改善您在Java中的答案:
1)除了&#39;之外还有其他空格字符。 &#39;,你必须检查所有。使用Character.isWhitespace()或(如果你像我一样老)&lt; =&#39; &#39;
2)你应该推迟制作StringBuilder直到你真正看到空格字符。如果你没有一个到底,只需返回原始字符串。
Java中的大多数人都会使用正则表达式进行搜索和替换,但是如果你必须为它编写一个实用函数,那么这样做会更好(在这些改进之后),因为它会是效率更高。
如果访问者然后要求你提供恒定的空间,那么最好的回答就是解释字符串在Java中是不可变的,所以你必须对带有StringBuilder参数然后修改的方法进行重载。有很多方法可以用其他流行语言来实现,比如C ++和C(orlp的答案),但它们都相当于采用可变的StringBuilder,所以不需要切换语言。
答案 2 :(得分:0)
采访中的问题“来自给定的字符串”(字面意思是你必须使用String str
作为输入),或者你只是假设你必须使用String对象而不是例如char[]
或StringBuilder
。
使用String
它无效。只要使用str.toCharArray()
之类的内容,就会分配至少与str
相同长度的新内存。并且你不能修改str
中的字符,正如已经多次提到的那样。