[英]How to reduce the number of for loops
我如何改进此代码,我获得了准确的输出,但似乎时间不长且不必要。 任何建议。
public class Test {
public static void main(String[] args) {
List<Integer> a = new ArrayList<Integer>();
a.add(1);
a.add(2);
List<Integer> b = new ArrayList<Integer>();
b.add(3);
b.add(5);
System.out.println(test(5, a, b));
}
public static long test(int n, List<Integer> a, List<Integer> b) {
// Write your code here
long retCnt = 0;
List<String> enemy = new ArrayList<String>();
for (int i = 0; i < a.size(); i++) {
enemy.add(a.get(i) + "" + b.get(i));
}
String tempstr = "";
int tempj = 1;
for (int m = 1; m <= n; m++) {
int temp = 1;
for (int i = 1; i <= n; i++) {
tempstr = "";
for (int j = tempj; j <= temp; j++) {
tempstr += j;
}
temp++;
if (!"".equalsIgnoreCase(tempstr)) {
if (isValidGroup(enemy, tempstr)) {
retCnt++;
} else {
break;
}
}
}
tempj++;
}
return retCnt;
}
public static boolean isValidGroup(List<String> enemy, String group) {
for (int i = 0; i < enemy.size(); i++) {
if (group.trim().toUpperCase().contains(String.valueOf(enemy.get(i).charAt(0)).toUpperCase())&& group.trim().contains(String.valueOf(enemy.get(i).charAt(1)).toUpperCase())) {
return false;
}
}
return true;
}
}
问题说明的简短描述。
我有一个敌人列表,其中分别包含输入数组列表和b中的一对,例如13和25。 我有一个n叫5,我必须生成可能的排列,这些排列应该不属于敌人列表。
如果需要进一步说明,请发表评论。
您的代码很慢。 如果n为100,则您的代码将需要执行超过1亿次计算。
但是,如果您直接跳过无效数字所在的索引,则可以使用一些二项式数学在O(N)中执行整个测试函数。 也可以使用以下非常简单的算法在O(N ^ 2)中完成。
我要节省内存和代码的第一件事是删除变量tempj和temp,因为您可以使用变量m和i来完成相同的工作,并且变量始终具有相同的关联值,并且无论如何都必须创建它们适当数量的迭代。
还要注意的另一件有用的事情是,tempj有时(在所有迭代的大约一半中,更精确些)会比temp大。 在所有这些情况下,您都不会找到任何有效的排列,因为j仅以递增的顺序从temp到tempj进行迭代。 换句话说,一半的计算是无用的。
Tempstr可以预先计算。
想象一下tempj为1且temp为3。然后J将执行1至2以及2至3的2次迭代。J已达到temp,因此您将temp加1。 Temp现在是4,Tempj仍然是1。
现在,J必须执行精确的前两个步骤才能从1变到3,然后再执行一个额外的步骤来变到4,即temp。 您可以跳过前面的两个步骤,因为您已经知道在执行它们之后tempstr会是什么样子。 无需重置j,而是随着温度的升高而不断增加。
这是O(N ^ 2)的代码段(不考虑isValidGroup()的复杂度,可以使用布尔数组轻松地优化它,您可以在其中标记N ^ 2中的无效位置)
String tempstr = "";
for(int start = 1; start <= n; start++) {
tempstr = "";
for(int end = start; end <= n; end++) {
tempstr += end;
if(isValidGroup(enemy, tempstr)) {
retCnt++;
} else {
break;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.