繁体   English   中英

如何减少for循环的次数

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM