有一个数组,这个数组是不规则的,我们应该找到一个最大数量(n),至少n个数字大于它(这个数字可能在数组中,可能不在数组中)
例如,如果我们给2 5 7 6 9,则数字4是最大数量,至少4个数字(或者大于它)大于4(5 6 7 9更大)
我解决了这个问题,但我认为它给出了大量数字的时间限制,所以我想以另一种方式解决这个问题 所以我使用合并排序进行排序,因为它采用 nlog(n),然后我使用计数器,如果我们有k数大于k,它从1到k计数我们再次计算,例如我们计数从1到4然后在5我们没有5个数字超过5,所以我们给k-1 = 4,这是我们的n。
它好还是可以给出时间限制?有人有另一个想法吗?
感谢
答案 0 :(得分:5)
在c++
中有一个名为std::nth_element
的函数,它可以在线性时间内找到数组的第n个元素。使用此函数,您应该找到N - n
- th元素(其中N
是数组中元素的总数)并从中减去1。
当您在C
中寻求解决方案时,您无法使用此功能,但您可以类似地实施解决方案。 nth_element
执行与qsort非常相似的操作,但它仅在第n个元素所在的数组部分执行分区。
现在让我们假设您已实施nth_element
。我们将执行二进制搜索和nth_element
的组合。首先,我们假设问题的答案是数组的中间元素(即第N / 2个元素)。我们使用nth_element
,我们找到N/2
元素。如果超过N/2
,我们知道问题的答案至少为N/2
,否则会更少。无论哪种方式,为了找到答案,我们将只继续使用N/2
元素创建的两个分区之一。如果这个分区是正确的(大于N/2
的元素),我们继续解决相同的问题,否则我们开始在M
元素的左侧搜索最大元素N/2
至少有x
个x + N/2 > M
更大的元素,1
。这两个子问题将具有相同的复杂性。您继续执行此操作,直到您感兴趣的间隔长度为nth_element
。
现在让我们证明上述算法的复杂性是线性的。第一个N
是nth_element
,第二个N/2
的线性执行操作,只考虑数组的一半将按N/4
的顺序执行操作 - 第三个N + N/2 + N/4 + ... + 1
的顺序等等。总而言之,您将按2 * N
的顺序执行操作。这个总和小于O(n*log(n))
,因此你的复杂性仍然是线性的。
您的解决方案渐渐慢于我上面提出的解决方案,因为它具有复杂性O(n)
,而我的解决方案具有{{1}}的复杂性。
答案 1 :(得分:0)
我会使用一个使用透视值的排序算法的修改变体。
原因是您希望对尽可能少的元素进行排序。
所以我会使用qsort
作为我的基本算法,让pivot元素控制哪个分区进行排序(你只需要排序一个)。