Algorithm 如何设计时间复杂度为O(n logn)的搜索算法?

Algorithm 如何设计时间复杂度为O(n logn)的搜索算法?,algorithm,time,logarithm,Algorithm,Time,Logarithm,描述一个O(nlogn)-时间算法,给定一组n个整数和另一个整数x,该算法确定S中是否存在两个元素,其和正好是x 我计划使用二进制搜索这个 ALGORITHM(S,x) S=Insertion-Sort() for i=1 to S.length n=x-S[i] if( Binary-Search(S,n) == true) return { S[i],n } Binary-Search(A, v) low=1 high=A.length while low ≤

描述一个O(nlogn)-时间算法,给定一组n个整数和另一个整数x,该算法确定S中是否存在两个元素,其和正好是x

我计划使用二进制搜索这个

ALGORITHM(S,x)
S=Insertion-Sort()
for i=1 to S.length
   n=x-S[i]
   if( Binary-Search(S,n) == true)
      return { S[i],n }


Binary-Search(A, v)
low=1
high=A.length

while low ≤ high
   mid=(low+high)/2

   if v = A[mid]
     return mid
   if v > A[mid]  
      low ← mid+1
   else
      high ← mid−1
 return NIL 

如何找到该算法的时间复杂度?如果T(n)不是(n logn),那么正确的算法是什么?

算法的整体顺序由单个片段的最高顺序决定。您将从一个插入排序开始,因此您已经失败了

如果要用O(n logn)版本替换排序算法,那么必须查看剩下的内容。有一个长度为n的循环,循环体调用二进制搜索。正确编码的二进制搜索是O(logn),因此结果应该是O(nlogn)。添加两个O(n logn)进程仍然会留下O(n logn)


有另一种更快的方法来完成第二步,但我会留给你去发现。它不会影响整体结果。

算法的整体顺序由单个片段的最高顺序决定。您将从一个插入排序开始,因此您已经失败了

如果要用O(n logn)版本替换排序算法,那么必须查看剩下的内容。有一个长度为n的循环,循环体调用二进制搜索。正确编码的二进制搜索是O(logn),因此结果应该是O(nlogn)。添加两个O(n logn)进程仍然会留下O(n logn)


有另一种更快的方法来完成第二步,但我会留给你去发现。它不会影响整体结果。

正如其他答案所指出的,您可以首先使用O(n logn)排序,然后在O(logn)时间内搜索每个元素的补码,从而总计为O(n logn)

但是,我认为您也可以执行以下操作以获得O(n)算法


注意,如果两个数字之和是x,其中一个必须>=x/2,另一个,正如其他答案所指出的,您可以首先使用O(n logn)排序,然后在每个元素的O(logn)时间内搜索每个元素的补码,从而总计为O(n logn)

但是,我认为您也可以执行以下操作以获得O(n)算法


注意,如果两个数字之和为x,则其中一个必须>=x/2,对于每个元素
i
,另一个:

  • 如果
    x-i
    在哈希表中,我们就有了我们的总和(
    i
    x-i
  • i
    插入哈希表

总运行时间-
O(n)
每个元素
i

  • 如果
    x-i
    在哈希表中,我们就有了我们的总和(
    i
    x-i
  • i
    插入哈希表

总运行时间-
O(n)

尝试上课和上班时间。首先,要在
O(nlogn)
中完成任务,您必须使用具有该时间复杂性的排序算法(例如mergesort)。然后,您可以利用这样一个事实,即数组被排序以执行
O(n)
中的任务(想想怎么做,您不需要进行二进制搜索)。总体复杂度将是两种算法中最高的(因为它们是依次完成的),即
O(nlogn)
。尝试上课和上班时间。首先,要在
O(nlogn)
中完成任务,必须使用具有该时间复杂度的排序算法(例如mergesort)。然后,您可以利用这样一个事实,即数组被排序以执行
O(n)
中的任务(想想怎么做,您不需要进行二进制搜索)。总体复杂度将是两种算法中最高的(因为它们是顺序进行的),即
O(nlogn)
。正如您所说,从主for循环调用n次的二进制搜索的时间复杂度为n logn。如果我使用合并排序代替插入排序,那么我的总时间将是
nlogn+nlogn
,这是
2nlogn
,因为合并排序的T(n)是nlogn。这是对的吗?@Ghost,你是对的,除了在O()符号中常量被删除-因此
2n log n
n log n
相同。正如你所说,从主for循环调用n次二进制搜索的时间复杂度是n logn。如果我使用合并排序代替插入排序,那么我的总时间将是
nlogn+nlogn
,这是
2nlogn
,因为合并排序的T(n)是nlogn。这是对的吗?@Ghost,你是对的,除了在O()符号中常量被删除-因此
2n log n
n log n
相同。