找出既不是第k个最大值也不是第k个最小值的元素的时间复杂度?

时间:2016-09-05 12:29:12

标签: algorithm sorting time-complexity

N 不同的数字不是按排序顺序给出的。选择一个数字的时间需要多长时间既不是第k个最小值也不是第k个最大值

我试过这样=>

取最初的k + 1个数字并在O(k log k)中对它们进行排序。然后在该排序列表中选取第k个数字,既不是第k个最小值也不是第k个最大值。

因此,时间复杂度= O(K log k)

示例=>

选择既不是第二最小值也不是第二最大值的数字。

array [] = {3,9,1,2,6,5,7,8,4}

取最初的3个数字或子数组= 3,9,1,排序的子数组将是= 1,3,9

现在拿起第二个元素3.现在,3不是第二个最小值,也不是第二个最大值。

现在,时间复杂度= O(k lg k)= O(2 lg 2)= O(1)。

3 个答案:

答案 0 :(得分:6)

如果N <1,问题是微不足道的。 ķ。否则,阵列中没有第k个最大或最小的元素 - 因此可以在O(1)时间内选择任何元素(例如第一个)。

如果N足够大,您可以采用大小为2k + 1的任何子集并选择中位数。然后你发现一个数字保证不是整个数组中第k个最大或最小的数字。事实上,你获得了更强大的东西 - 它保证它不会在排序数组中的前k个或最后k个数字中。

在O(M)时间内找到M个事物的中位数,因此该算法在O(k)时间内运行。

我认为这对于大N来说是渐近最优的 - 任何考虑少于k项的算法都不能保证它选择的数字不是整个数组中的第k个最小值或最大值。

如果N不足够大(特别是N <2k + 1),则可以在O(N)时间内找到最小值(或第二个最小值,如果k = 1)。由于k <= N&lt; 2k + 1,这也是O(k)。

有三种情况不存在解:(k = 1,N = 1),(k = 1,N = 2),(k = 2,N = 2)。

如果仅考虑k <= N的情况,则整个算法的复杂度为O(k)。如果你想要包括那些琐碎的案例那么它有些混乱。如果I(k <= N)是k <= N时的函数1,否则为0,则更严格的界限是O(1 + k * I(k <= N))。

答案 1 :(得分:1)

我认为在您的解决方案中必须注意许多要点:

首先,在解决方案中需要使用2k + 1个元素而不是k + 1。更具体地说,你采取:

array[] = {3,9,1,2,6,5,7,8,4}

Take initial 3 numbers or subarray = 3,9,1 and sorted subarray will be = 1,3,9

Now pick up 2nd element 3. Now, 3 is not the 2nd minimum nor 2nd maximum .

但要检查3 is not the 2nd minimum nor 2nd您是否可以使用k + 1元素执行此操作:subarray = 3,9,1您必须检查数组以查看最大2和最小值是多少并检查您的溶液

另一方面,通过获取2k + 1个元素并对它们进行排序,因为你的元素是不同的,你会知道k + 1元素比k个第一个元素更大,而更小的元素来自你排序的子数组的k个最后元素。

在您的示例中,您可以看到:

array [] = {3,9,1,2,6,5,7,8,4} subarray [] = {3,9,1,2,6}然后对子阵列进行排序:{1,2,3,6,9},并给出答案数字3。

您的解决方案不适合的示例: array [] = {9,8,2,6,5,3,7,1,4}你的算法将返回数字2,即第二分钟。

至于复杂性。通过2k + 1个元素,它不会改变你找到的复杂性,因为它将是O((2k + 1)log(2k + 1)),即O(klog(k) )。

显然,如果n&lt; 2k + 1上述算法不能正常工作,那么你必须对整个数组进行排序,这将采用nlog n,但在这种情况下n&lt; 2k + 1所以它O(klogk)

最后基于上面的算法将是O(klog k)。可能令人困惑的一个问题是问题有两个参数k,n。如果K比n小得多,这是一个有效的算法,因为你没有&# 39; t需要查看和缩短n-size数组但是当k,n非常接近时,它与排序n-size数组相同。

你应该理解的另一件事是,当输入n被赋予算法时,大O符号是测量时间复杂度的方式,并且显示了大输入n的算法的渐近行为。 O(1)表示算法在恒定时间内运行 ALWAYS 。所以当你引用时最终:

Now, time complexity = O(k lg k) = O(2 lg 2) = O(1).

这不是正确的,您必须测量复杂度,其中k是输入变量而不是常量,这显示了算法对随机输入k的行为。显然,上述算法不需要O(1)(或其他恒定时间)它需要O(k log(k))。

最后,在寻找更好的方法之后,如果你想要一种更有效的方法,你可以在O(n)中找到kth min和kth max(n是数组的大小)。并且有一个循环进入O(n)你可以简单地选择第一个与第k个最小值和最大值不同的元素。我认为O(n)是你可以得到的最低时间复杂度,因为找到kth min和max取最小O(n)。

关于如何找到kth min,在O(n)中的最大值,你可以在这里看到: How to find the kth largest element in an unsorted array of length n in O(n)?

这个解是O(n)而前面的解是O(klog k)。现在k参数接近n,如上所述,它与O(n log(n))相同,所以在这个场合O(n)解决方案更好。但是如果大多数时间k远小于n那么那么O(k log k)可能会更好.O(n)解决方案(第二种解决方案)的好处在于所有在不考虑k的情况下,它需要O(n),因此它更稳定,但如小k所述,第一种解决方案可能更好(但在最坏的情况下,它可以达到O(nlogn))。

答案 2 :(得分:1)

您可以使用radix-sort在伪线性时间内对整个列表进行排序,并在恒定时间内选择第k个最大元素。

总的来说,假设基数的大小远小于n或者你使用Selection algorithm,它将是最坏情况的O(n)算法。

O(n)是这里的绝对下界。没有办法比线性更好,因为如果列表没有排序,你至少需要检查一切,否则你可能会错过你正在寻找的元素。