【问题标题】:How to design a search algorithm with time complexity O(n log n)?如何设计一个时间复杂度为 O(n log n) 的搜索算法?
【发布时间】:2013-08-27 16:40:16
【问题描述】:

描述一个 O(n log n) 时间的算法,给定 n 个整数的集合 S 和另一个整数 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 log n),那么正确的算法是什么?

【问题讨论】:

  • 尝试上课和上班。
  • 首先,要在O(nlogn) 中完成您的任务,您必须使用具有该时间复杂度的排序算法(例如归并排序)。然后,您可以利用数组已排序的事实在O(n) 中完成您的任务(想想如何,您不需要二进制搜索)。总体复杂度将是两种算法中最高的(因为它们是按顺序完成的),即O(nlogn)

标签: algorithm time logarithm


【解决方案1】:

算法的整体顺序由各个部分的最高顺序决定。您从插入排序开始,其 worst-case performance is O(n^2) 所以您已经失败了。

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

还有另一种更快的方法来执行第二步,但我会留给你去发现。不会影响整体效果。

【讨论】:

  • 如你所说,从主for循环调用n次的二分查找时间复杂度为n logn .如果我使用 Merge-Sort 代替插入排序,那么我的总时间将是 nlogn + nlogn,即 2 nlogn,因为 Merge-的 T(n)排序是 nlogn。对吗?
  • @Ghost,你是对的,除了在 O() 表示法中常量被删除 - 因此 2n log nn log n 相同。
【解决方案2】:

正如其他答案指出的那样,您可以首先使用 O(n log n) 排序,然后在每个元素的 O(log n) 时间内搜索每个元素的补码,因此加起来为 O( n log n) 总体。

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

请注意,如果两个数之和为 x,则其中一个必须 >= x/2,另一个必须为

现在为下部数组中的所有元素 i 构建一个 x-i 哈希表。这又需要 O(n) 时间。

现在在每次查找的恒定时间内搜索哈希表中高数组中的每个元素。因此,这也是 O(n)。

因此,总体复杂度为 O(n)。

【讨论】:

    【解决方案3】:

    对于每个元素i

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

    总运行时间 - O(n)

    【讨论】:

      猜你喜欢
      • 2015-06-12
      • 2011-07-09
      • 2015-05-25
      • 1970-01-01
      • 1970-01-01
      • 2021-06-22
      • 2019-05-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多