如何在Java中以O(1)时间在数组中查找重复项?

时间:2019-06-18 07:34:44

标签: java algorithm performance sorting compare-and-swap

我被赋予一项任务,以在O(1)时间中在int数组中查找重复项。 我的方法是先对数组进行排序,然后使用线性搜索找到重复项。我首先通过交换数字来对数组进行排序:

$interval(function() {
        $.getScript('//script.js')
            .done(function( data, textStatus, jqxhr ) {
                console.log(g_signal_strength);
            })
            .fail(function( jqxhr, settings, exception ) {
                console.log('fail');
            });
    }, 5000);

但是该算法的效率为 O(i * j),这对于解决方案不是必需的。我尝试使用递归对数组进行排序:

for(int i = 0;i<ar.length;i++) {
    for (int j = i + 1; j < ar.length; j++) {
        if (ar[i] > ar[j]) {
            buk = ar[i];
            ar[i] = ar[j];
            ar[j] = buk;
        }
    }
}

但是,目前看来这似乎行不通。请提供建议/替代方法来对数组进行排序,我已经多次遇到此问题。

问题是:找到一个数字,该数字在线性时间内使用小于O(n)的空间重复进行,并依次遍历流O(1)次。

1 个答案:

答案 0 :(得分:4)

在数学上不可能在O(1)中找到重复项。您必须至少检查一次数组的所有N个元素,以测试每个元素是否重复。这至少是 N个操作,因此复杂度上的下界O(N)

提示:如果您使用(例如)O(N)来记录已经看到的每个值,则可以在HashSet中进行操作。问题是HashSet是一个需要大量空间的数据结构。


  

请提供建议/其他方法来对数组进行排序,我已经多次遇到此问题。

对整数数组进行排序的简单方法是使用Arrays::sort(int[])。那将是O(NlogN)

从理论上说,可以对整数数组进行排序,而不是对O(NlogN)进行排序,但前提是您可以在整数范围内设置边界。查找counting sort。复杂度为O(max(N, R),其中R是最小数字和最大数字之间的差。问题在于,O(R)可能比O(N) ...大得多,具体取决于输入。

但是,如果您知道M可能小于NlogN,则可以使用计数排序的变体,并且仅使用O(M)位多余的空间来重复删除O(max(M, N))中的数组。 (我将让您找出细节。)