假设您有List
Strings
或其他任何内容,并且您希望生成另一个List
,其中包含来自原始strings
的两个list
的所有可能组合1}}(汇总在一起),除了使用嵌套的for
循环将String与所有其他循环结合起来之外,还有更有效的方法吗?
一些示例代码:
for(String s: bytes) {
for(String a: bytes) {
if(!(bytes.indexOf(a) == bytes.indexOf(s))) {
if(s.concat(a).length() == targetLength) {
String combination = s.concat(a);
validSolutions.add(combination);
}
}
}
}
随着list
原始Strings
的大小增加,执行时间变得非常糟糕。
更有效的方法吗?
答案 0 :(得分:3)
你不能比 O(N ^ 2)更好,因为有很多种组合。但是你可以通过移除indexOf
调用来加速你的算法(从 O(N ^ 3)):
for(int i=0; i<bytes.length(); i++) {
for(int j=0; j<bytes.length(); j++) {
string s = bytes[i];
string a = bytes[j];
if (i != j && s.length() + a.length() == targetLength) {
validSolutions.add(s.concat(a));
}
}
}
答案 1 :(得分:3)
您可以通过设置i != j
来避免检查j = i + 1
条件。此外,bytes.length()
之类的东西会在两个循环的每次迭代中得到评估 - 将其保存为值并重用。在循环内调用a.length()
会多次询问相同字符串的长度 - 您也可以在其上保存一些运行时。以下是更新:
int len = bytes.length();
int aLength;
String a, b;
for(int i=0; i<len; i++) {
a = bytes[i];
aLength = a.length();
for(int j=i; j<len; j++) {
b = bytes[j];
if (b.length() + aLength == targetLength) {
validSolutions.add(b.concat(a));
validSolutions.add(a.concat(b));
}
}
}
编辑:j = i
,因为您想要考虑字符串与其自身的组合;此外,您还需要添加a.concat(b)
,因为循环中从不考虑此组合,但它是有效的字符串
答案 2 :(得分:1)
除了Jimmy和lynxoid所说的,总长度受限制的事实可以进一步优化。按照长度的顺序对字符串进行排序,然后对于每个s
,您知道只需要a
a.length() == targetLength - s.length()
。{/ p>
所以一旦你击中一个比你更长的字符串就可以突破内部循环(因为所有其余部分都会更长),你可以从“正确”的地方开始,例如使用下限二进制文件搜索阵列。
复杂性仍然是O(n ^ 2),因为在最坏的情况下,所有字符串都是相同的长度,等于totalLength
的一半。通常虽然它应该比考虑所有字符串对要好一些。