Algorithm 这个搜索算法是最优的吗?
我有两个列表,L和M,每个列表包含数千个64位无符号整数。我需要找出L的任意两个成员之和是否本身就是M的一个成员 是否有可能改进以下算法的性能Algorithm 这个搜索算法是最优的吗?,algorithm,language-agnostic,optimization,search,Algorithm,Language Agnostic,Optimization,Search,我有两个列表,L和M,每个列表包含数千个64位无符号整数。我需要找出L的任意两个成员之和是否本身就是M的一个成员 是否有可能改进以下算法的性能 Sort(M) for i = 0 to Length(L) for j = i + 1 to Length(L) BinarySearch(M, L[i] + L[j]) 您可以通过使用哈希表(排序M数组除外)来避免二进制搜索。您可以通过使用哈希表(排序M数组除外)来避免二进制搜索。您可以通过使用哈希表(排序M数组除外)来代替
Sort(M)
for i = 0 to Length(L)
for j = i + 1 to Length(L)
BinarySearch(M, L[i] + L[j])
您可以通过使用哈希表(排序M数组除外)来避免二进制搜索。您可以通过使用哈希表(排序M数组除外)来避免二进制搜索。您可以通过使用哈希表(排序M数组除外)来代替排序
M
以n*log(n)
为代价,创建一个哈希集
您还可以在迭代时将所有和存储在另一个哈希集中,并添加检查以确保不执行两次相同的搜索。您可以创建哈希集,而不是以
n*log(n)
为代价对M
进行排序
您还可以在迭代时将所有和存储在另一个哈希集中,并添加一个检查,以确保不会执行两次相同的搜索。或者,将L的所有成员添加到哈希集lSet,然后在M上迭代,对M中的每个M执行以下步骤:
这将需要更少的迭代次数,但需要更多的内存。如果要提高速度,您需要为结构预先分配内存。或者,将L的所有成员添加到hashset lSet,然后在M上迭代,对M中的每个M执行以下步骤:
这将需要更少的迭代次数,但需要更多的内存。如果要提高速度,您需要为结构预先分配内存。问题中示例代码的复杂性是O(m log m+l2 log m),其中l=| l |和m=| m |,因为它对l(O(l2))中的每一对元素运行二进制搜索(O(log m)),m首先排序 假设哈希表插入和查找是O(1)操作,用哈希表替换二进制搜索将复杂性降低到O(l2)
这是渐近最优的,只要你假设你需要处理列表L上的每一对数字,因为有O(l2)这样的对。如果L上有几千个数字,它们是随机的64位整数,那么您肯定需要处理所有对。问题中示例代码的复杂性是O(m log m+l2 log m),其中L=| L |和m=| m |,因为它对L(O(l2))中的每一对元素运行二进制搜索(O(log m)),m首先排序 假设哈希表插入和查找是O(1)操作,用哈希表替换二进制搜索将复杂性降低到O(l2) 这是渐近最优的,只要你假设你需要处理列表L上的每一对数字,因为有O(l2)这样的对。如果L上有几千个数字,它们是随机的64位整数,那么您肯定需要处理所有的对。(我假设您的目标是找到L中的所有对,它们的总和等于m) 忘记哈希表吧 对两个列表进行排序 然后做算法的外循环:遍历L中的每一个元素i,然后遍历L中的每一个较大的元素j。这样,形成和,检查它是否在M中 但不要使用二进制搜索:只需从上次查看的位置进行线性扫描。假设你在处理一些值i,你有一些值j,后面跟着一些值j’。当搜索(i+j)时,您将到达M中找到该值的点,或者第一个最大值。你现在正在寻找(i+j');因为j'>j,你知道(i+j')>(i+j),所以它在M中不可能比你得到的最后一个位置更早。如果L和M都是平滑分布的,那么很有可能在M中找到(i+j')的点只差一点点 如果阵列分布不平滑,那么比线性扫描更好的可能是某种跳跃扫描——一次向前看N个元素,如果跳跃太远,则将N减半 我相信这个算法是O(n^2),它和任何提出的散列算法一样快(有一个O(1)基元运算,但仍然要做O(n**2)。这也意味着你不必担心O(n log n)排序。它比散列算法具有更好的数据局部性——它基本上由阵列上的成对流式读取组成,重复n次
编辑:我编写了Paul Baker的原始算法、Nick Larsen的哈希表算法和我的算法的实现,以及一个简单的基准测试框架。实现很简单(哈希表中的线性探测,线性搜索中没有跳过),我不得不猜测各种大小参数。有关代码,请参阅。我欢迎对任何实现、框架和参数的更正或建议 对于分别包含3438个项目的L和M,其值范围为1到34380,且Larsen哈希表的负载系数为0.75,则运行的中值时间为:
- 贝克(二进制搜索):423716646ns
- 拉森(哈希表):733 479 121纳秒
- 安德森(线性搜索):62077597纳秒