【发布时间】:2015-05-13 17:04:24
【问题描述】:
在做 LeetCode 125 时,我采用了一个简单的算法:
- 修剪字符串。
- 遍历修剪后的字符串以验证它是否为回文。
修剪后的字符串存储为 String 或 ArrayList。但是,遍历修剪后的字符串(存储为字符串)导致“超时”,而遍历 ArrayList 被接受。由于除了 String/ArrayList 之外,这两段代码完全相同,我想知道 Java 处理 String 时它可能比 ArrayList 慢得多。
谁能告诉我差异来自哪里?
代码 1(按字符串):
public class Solution {
public boolean isPalindrome(String s) {
s = s.toLowerCase();
String trimmed = "";
for (int i=0; i<s.length(); i++) {
char ch = s.charAt(i);
if (ch >= 'a' && ch <= 'z' || ch >= '0' && ch <= '9') {
trimmed = trimmed + ch;
}
}
for (int i=0; i<(trimmed.length()+1)/2; i++) {
if (trimmed.charAt(i) != trimed.charAt(trimmed.length() -1 -i)) {
return false;
}
}
return true;
}
}
代码 2,(通过 ArrayList):
public class Solution {
public boolean isPalindrome(String s) {
s = s.toLowerCase();
List<Character> trimmed = new ArrayList<Character>();
for (int i=0; i<s.length(); i++) {
char ch = s.charAt(i);
if (ch >= 'a' && ch <= 'z' || ch >= '0' && ch <= '9') {
trimmed.add(ch);
}
}
for (int i=0; i<(trimmed.size())/2; i++) {
if (trimmed.get(i) != trimmed.get(trimmed.size() - 1 -i)) {
return false;
}
}
return true;
}
}
【问题讨论】:
-
如果效率是主要关注点,您可以轻松地将字符验证融合到回文检测中,并完全避免创建任何临时对象(基本上从两端迭代,跳过被拒绝的字符)。
-
@Durandal。谢谢你的评论。我知道这个算法不够好,因为它可以通过遍历原始字符串一次来验证,而不是创建一个新的修剪过的字符串。我很好奇性能差异是怎么来的,以避免将来出现同样的陷阱。仍然感谢您的评论。
标签: java string performance arraylist jvm