【发布时间】:2015-08-22 17:44:32
【问题描述】:
这是我针对 leetcode 中的一个问题的解决方案。通过我的推论,我得出结论它具有总体 O(N^2) 时间复杂度。但是,我想对此进行确认,以免在判断算法的时间/空间复杂度时不会继续犯同样的错误。
哦,问题是这样的:
给定一个输入字符串,逐字反转字符串。 例如“我就是你”==“你就是我”
代码如下:-
public String reverseWords(String s) {
//This solution is in assumption that I am restricted to a one-pass algorithm.
//This can also be done through a two-pass algorithm -- i.e. split the string and etc.
if(null == s)
return "";
//remove leading and trailing spaces
s = s.trim();
int lengthOfString = s.length();
StringBuilder sb = new StringBuilder();
//Keeps track of the number of characters that have passed.
int passedChars = 0;
int i = lengthOfString-1;
for(; i >= 0; i--){
if(s.charAt(i) == ' '){
//Appends the startOfWord and endOfWord according to passedChars.
sb.append(s.substring(i+1, (i+1+passedChars))).append(" ");
//Ignore additional space chars.
while(s.charAt(i-1) == ' '){
i--;
}
passedChars = 0;
}else{
passedChars++;
}
}
//Handle last reversed word that have been left out.
sb.append(s.substring(i+1, (i+1+passedChars)));
//return reversedString;
return sb.toString();
}
我认为这是一个 O(N^2) 算法:-
- 循环 = O(n)
- StringBuilder.append = O(1)
- 子字符串方法 = O(n) [从 Java 7 开始]
关于这一点,如果其他人有比这更好的解决方案,请随时分享! :)
我的目标是一次性解决方案,因此选择在循环之前不拆分字符串。
感谢您的帮助!
编辑:我的意思是询问包含循环的代码部分的时间复杂度。如果问题具有误导性/混淆性,我提前道歉。整个代码块是为了澄清目的。 :)
【问题讨论】:
-
抽象时间复杂度计算完全取决于你算作 1 次操作。
-
如果您将访问或复制一个字母作为您的基本操作,它可以在线性时间和线性空间中完成。
-
它需要正确处理Unicode吗?点必须去哪里?您有更多示例的完整规范吗?
-
@biziclop 你好!谢谢你的建议。我已经编辑了我的原始帖子,以澄清我最好奇的代码部分——就时间复杂度而言。你能进一步解释一下你在线性时间/空间中解决问题的意思吗?
-
@Thomas 嗨!没有。您不必担心处理 Unicode。我提供的代码是一个公认的解决方案,所以不用担心它不正确。 :) 我只是对代码“循环”部分的时间复杂度感到好奇。完整的规范/问题可以在 leetcode 的“Reverse Words in a String”标题下找到。
标签: java algorithm performance substring time-complexity