简体   繁体   English

如何使 java 嵌套循环高效

[英]How to make java nested loops efficient

I currently need to code a program that does a pairwise comparison to find matching pairs in an int list, but the only way I can think of doing it is through a nested for loop.我目前需要编写一个程序来进行成对比较以在 int 列表中找到匹配对,但我能想到的唯一方法是通过嵌套的 for 循环。 Is there a way to make the time complexity O(n) instead of the O(n^2) of a nested for loop?有没有办法使嵌套 for 循环的时间复杂度为 O(n) 而不是 O(n^2)?

int[] arr = new int[n];
int total = 0;
for (int i=0; i<n; i++){
    for (int j=i+1; j<n; j++){
        if (arr[i] == arr[j]){
            total++;
        }
    }
}

Looks like you are only worried about the count.看起来你只担心计数。 So, if modifying an array is not an issue then, apply quick sort in O(nlog(n)) and then count the neighbours in O(n).因此,如果修改数组不是问题,则在 O(nlog(n)) 中应用快速排序,然后在 O(n) 中计算邻居。

You can use a HashSet which has O(1) complexity of contains method - because hashCode of Integer value in Java is well distributed (it's just a value of the Integer ) you should have constant complexity always您可以使用具有O(1)复杂度的HashSet contains方法 - 因为 Java 中Integer值的hashCode分布良好(它只是Integer的值)您应该始终具有恒定的复杂性

HashSet<Integer> set = new HashSet();
for (int i=0; i<n; i++) {
    if(set.contains(arr[i])) {
        total++;
    } else {
        set.add(arr[i]);
    }
}

Read more here:在这里阅读更多:


There's also one additional algorithm that could be implemented here but it require some data limitations (due to the max length of array on your machine).还有一种可以在此处实现的附加算法,但它需要一些数据限制(由于您机器上数组的最大长度)。

You could just create an int array yourarray initialized with 0 with a length of max(arr) + 1 .您可以只创建一个 int 数组yourarray并用0初始化,长度为max(arr) + 1 Then you are iterating over arr every time executing yourarray[arr[i]]++ and then you are iterating over yourarray checking where the value is greater than 1 - if it this then it means that this value has to repeat然后你在每次执行yourarray[arr[i]]++时迭代arr然后你在迭代yourarray检查值大于1的位置 - 如果是这样那么它意味着这个值必须重复

O(n) solution. O(n) 解决方案。 Try this.尝试这个。

public static void main(String[] args) {
    int[] arr = {0, 1, 2, 3, 4, 3, 2, 3};
    int total = arr.length - (int)IntStream.of(arr).distinct().count();
    System.out.println(total);
}

output: output:

3

I think you can use a HashSet to resolve this problem.我认为您可以使用 HashSet 来解决此问题。 The HashSet in JAVA doesn't allow insert into a duplicate element. JAVA 中的 HashSet 不允许插入重复元素。 So you can use it to making the time complexity become O(n).所以你可以用它来使时间复杂度变成 O(n)。

        int[] arr = new int[n];
        Set<Integer> set = new HashSet<Integer>();
        Integer total = 0;
        for (int x: arr)
        {
            if (!set.add(x))
            {
               total++;
            }
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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