【问题标题】:find 4th smallest element in linear time在线性时间内找到第四小的元素
【发布时间】:2020-01-17 13:27:30
【问题描述】:

所以我在大约 2 个月前给了我一个练习,内容如下:

给定 n (n>=4) 个不同的元素,设计一个分治算法来计算第 4 个最小的元素。在最坏的情况下,您的算法应该在线性时间内运行。

我遇到了这个问题非常困难,只能找到在最坏情况 O(n*k) 下运行的相关算法。经过几周的尝试,我们在老师的帮助下设法“解决”了这个问题。最终算法如下:

Rules: The input size can only be of size 2^k

(1): Divide input into n/2. One left array, one right array.

(2): If input size == 4, sort the arrays using merge sort.
     (2.1) Merge left array with right array into a new result array with length 4. 
     (2.2) Return element at index [4-1]

(3): Repeat step 1


This is solved recursively and our base case is at step 2. Step 2.2 means that for all
of our recursive calls that we did, we will get a final result array of length 4, and at that
point, we can justr return the element at index [4-1].

使用这个算法,我的老师声称它在线性时间内运行。我对该语句的问题是,我们正在挖掘输入,直到我们到达输入大小为 4 的子数组,然后对其进行排序。因此,对于 8 的输入大小,我们将对 2 个长度为 4 的子数组进行排序,因为 8/4 = 2。无论如何,这如何是线性时间?我们仍在对整个输入大小进行排序,但不是按块排序吗?这对我来说真的没有意义。如果我们对整个输入大小进行排序,或者将其划分为大小为 4 的子数组,然后像这样对它们进行排序,这并不重要?还会是 O(n*log(n)) 的最坏时间吗?

希望对此有一些解释!

【问题讨论】:

  • 第 2.2 步中的 [4-1] 是什么?
  • 您的算法不完整。您错过了 (2) 中的 else 情况。如果输入大小大于 4,你会返回什么?你在哪里进行递归调用,你如何处理结果?
  • 如果超过 4 个,我们也对它进行左右递归!
  • @Raj 返回索引 4-1 处的元素

标签: algorithm sorting time-complexity


【解决方案1】:

为了证明算法在线性时间内运行,我们稍微修改一下(我们只会改变划分和合并块的顺序,仅此而已):

(1): Divide input into n/4 blocks, each has size 4.

(2): Until there is more than one block, repeat:
        Merge each pair of adjacent blocks into one block of size 4.
        (For example, if we have 4 blocks, we will split them in 2 pairs -
        first pair contains first and second blocks,
        second pair contains third and fourth blocks.
        After merging we will have 2 blocks -
        the first one contains 4 least elements from blocks 1 and 2,
        the second one contains 4 least elements from blocks 3 and 4).

(3): The answer is the last element of that one block left.

证明:事实是,恒定长度的数组(在您的情况下为 4)可以在恒定时间内排序。令 k = log(n)。循环 (2) 运行 k-2 次迭代(在每次迭代中,剩余元素的计数除以 2,直到剩下 4 个元素)。

在第 i 次迭代 (0

mergeOperationsCount = 2^(k-3) + 2^(k-4) + .... + 2^(k-(k-3)) =
    = 2^(k-3) * (1 + 1/2 + 1/4 + 1/8 + .....) < 2^(k-2) = O(2^k) = O(n)

由于我们可以在恒定时间内合并每一对(因为它们具有恒定的大小),并且我们所做的唯一操作是合并对,因此算法在 O(n) 中运行。

在这个证明之后,我想注意到还有另一个线性算法是微不足道的,但它不是分而治之的。

【讨论】:

  • 嗯,好吧!所以说我现在会改变问题以找到第 k 个最小的元素。那么不会有线性时间算法正确吗?我们可以说只求解第 4 个最小元素是可行的,因为如果我们让输入大小增长到无穷大,那么 4 与实际输入大小没有关联?
  • 有一个线性时间算法可以在线性时间内找到第k个最小元素:en.wikipedia.org/wiki/Selection_algorithm
  • 但是如果 4 不是常数,您问题中的算法将无法在线性时间内工作。
  • 啊,明白了!是的,我和你在一起。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-12
  • 1970-01-01
  • 2018-10-07
  • 2012-10-22
  • 1970-01-01
  • 2014-09-01
  • 1970-01-01
相关资源
最近更新 更多