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)。
答案 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)是这里的绝对下界。没有办法比线性更好,因为如果列表没有排序,你至少需要检查一切,否则你可能会错过你正在寻找的元素。