簡體   English   中英

如何有效地計算數組項之間的差異,並找出多少差異小於某個特定值?

[英]How to efficienlty calculate the difference between array items and find out how many differences are less than a certain value?

我有一個數組,需要計算每個項目與所有其他項目之間的差。 如果差異小於或等於某個值(限制),我必須將其計為1。

我使用蠻力方法實現了它:

for (int i = 0; i < n; i++) {
    int j = 0;
    while (j < n) {

        if (Math.abs(arr1[i] - arr1[j]) <= limit) {
            sum = sum + 1;
        }
        j++;
    }
}

現在,我正在尋找優化的解決方案,因為這里的時間復雜度是O(n^2) 如果要避免2個循環,什么是解決此問題的好方法?

如果必須確定數組中每對元素之間的差異是否小於或等於限制,則最好對數組進行排序(O(NlogN))。

現在,對於排序數組中的每個元素x,您必須找到值在x-limit和x + limit之間的元素范圍的長度。 可以在O(logN)時間內使用二進制搜索(即調用Arrays.binarySearch(sortedArray, x - limit)Arrays.binarySearch(sortedArray, x + limit) )找到此內容。 您將該范圍的長度加到總和中。

由於您必須對每個元素重復該操作,因此總時間為O(NlogN)。

最后,由於您要對每對進行兩次計數,因此必須將結果除以二。

總運行時間為O(NlogN) + O(NlogN) = O(NlogN)

順便說一句,您當前的實現似乎不正確:

  1. 您正在將每個元素與其自身進行比較,該元素的總和將具有n的額外值。

  2. 您將每對元素進行兩次比較,因此每對足夠接近的元素將被計數兩次。

編輯:實際上,由於不是只對每個接近對進行兩次計數然后除以2,因此,如果我們僅對array[i] (不包括)和array[i] + limit (包括)之間的元素數進行計數,則可以對這些對進行一次計數)。 這意味着為每個索引運行一次二進制搜索就足夠了。

這是一個正在運行的示例:

public static int comparePairs (int[] arr1, int limit) {
    int sum = 0;
    Arrays.sort (arr1);
    for (int i = 0; i < arr1.length - 1; i++) {
        int last = Arrays.binarySearch (arr1, arr1[i] + limit);
        if (last > 0) {
          sum += last - i;
        } else {
          sum += -last - i - 2;
        }
    }
    return sum;
}

請注意,它不支持重復元素,因此需要進行一些調整才能使用重復元素。

例如,它為數組{2,6,4,3,1,5}返回9 ,並為極限2 (兩對為(1,2)(1,3)(2,3)(2,4) (3,4)(3,5)(4,5)(4,6)(5,6))。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM