两个大小为100万的数组中的第一个常见数字

时间:2015-06-16 16:38:39

标签: java arrays algorithm

我有两个非常大的整数数组,每个数组的大小约为1百万。我必须找到两个数组中都存在的第一个整数。

我尝试使用一套来做到这一点。

(1)同时遍历每个数组并在集合中插入两个数组的元素。

(2)每当set拒绝接受这是第一个交集时。

int Solution(int A[], int B[])
{
    Set s = new HashSet();
    for (int i = 0 ; ; i++)
    {
        if ( i < A.length )
        {
            if( !s.Add(A[i]) )
                System.out.println(A[i]);
        }
        if ( i < B.length )
        {
            if( !s.Add(B[i]) )
                System.out.println(B[i]);
        }
    }
}

我们可以改进此解决方案以减少时间复杂度吗?

由于

5 个答案:

答案 0 :(得分:5)

  

如果class Migration(migrations.Migration): run_before = [ ('core_app', '0001_initial'), ] A={1,2,3} 1是数字,因为它首先出现在B={2,1,3}

这意味着您的算法在某些情况下不会产生正确的答案。考虑这些数据:

A

你的算法将返回2而不是1,因为在第二次插入两个集合后会检测到2,而你需要将A = {1, 2, 3, 4, 5, 6, 7} B = {7, 2, 3, 4, 5, 6, 1} 迭代到最后才能检测到1。

根据您的规范为您提供正确解决方案的一种方法是将B的所有元素加载到哈希集中,然后迭代B,直到您在集合中获得命中由A中的数字组成。这种方法是O(N a + N b )。

B

答案 1 :(得分:2)

与评论相反,排序和二元搜索不是最有效的。

假设两个数组的大小均为N,则会填充哈希表,然后用于检测时间准O(N)中的重复项。

通过约束,排序将花费时间O(N Lg(N)),并在最坏的情况下进行后续二进制搜索O(N Lg(N))

无论如何,如果您的数据已经排序或者由于某种原因(桶排序?)可以廉价排序,请不要使用二进制搜索,导致O(N Log(N)),但合并,在{{1 }}。

此外,如果整数的范围有限,例如不超过25个有效位(如0到33554431),则使用位数组可能是有利的。它需要4MB的空间(就像你的百万整数一样),时间O(N)用于初始化和检测重复项,代码非常简单快捷。

答案 2 :(得分:1)

您可以使用时间最短的n log n的合并排序,然后使用最差情况log n的二进制搜索来获得总的最差时间(抱歉没有做到这一点)数学有一段时间可能会关闭)O(n log (log n^2))

答案 3 :(得分:0)

简单线性解决方案:

可以在O(n+m)时间(平均)和O(n)空间(n是第一个数组的大小完成,m是第二个数组的大小数组)。

set = new empty hash set
for each x in arr2:
    set.add(x)
for each x in arr1 in ascending order:
    if set.contains(x):
        return x
//if here, no duplicates
return null

内存消耗略有改善:

它可以改进到O(min{n,m})空间,首先检查哪个数组较小,如果第二个 - 做与建议相同的算法,否则,加载到地图(x,i) - (元素, index)迭代第二个列表,找到匹配的最小i,然后返回:

具有更好内存复杂性的方法的伪代码:

def secondSmaller(arr1,arr2):
    set = new empty hash set
    for each x in arr2:
        set.add(x)
    for each x in arr1 in ascending order:
        if set.contains(x):
            return x
    //if here, no duplicates
    return null
def firstSmaller(arr1,arr2):
    map = new empty hash map
    for each x in arr1 with index i:
        map.add(x,i)
    minimal = infinity
    minVal = null
    for each x in arr2:
         if set.contains(x):
         i = map.get(x)
         if i < minimal:
            minimal = i
            minVal = x
     return minVal
if arr1.size() > arr2.size():
     return secondSmaller(arr1,arr2)
else return firstSmaller(arr1,arr2)

相关主题: How do I calculate the delta (inserted/deleted/moved indexes) of two lists?

作为旁注,这与Element Distinctness Problem密切相关,我怀疑它可以比这更有效地完成,因为bounds of element distinctness problem较低。

答案 4 :(得分:0)

对一个java 32位data[-1] <- answer$str[as.matrix(data[-1])] # name q1 q2 q3 # 1 a TRUE YES GREATER # 2 a LESS YES TRUE # 3 a YES NONE FALSE # 4 b NO NO YES 或更多的数组进行排序通常可以使用基数排序在int时间内完成任何固定大小的整数。对两个数组进行排序并合并它们您会在O(N)时间内找到所有公共号码。

此算法找到的第一个数字是最小公共数字,可能是的解释。两个数组共有的第一个数字