我有两个非常大的整数数组,每个数组的大小约为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]);
}
}
}
我们可以改进此解决方案以减少时间复杂度吗?
由于
答案 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)
时间内找到所有公共号码。
此算法找到的第一个数字是最小公共数字,可能是的解释。两个数组共有的第一个数字