找到第N个最大数量的INT数组的最快方法是什么?

时间:2015-12-21 12:26:51

标签: c# algorithm

我想要一个更快的函数来在C#中找到第N个最大数量的Int数组。此函数采用N和Array并返回该数字的索引

这是我已经拥有的。它只是对数组进行排序,然后返回该数字的索引。 效果很好但我不确定这是否是最快的方法。没有完全排序的算法似乎合乎逻辑。

tableView

一些结果:

static int myFunction(int[] array, int N){
    int[] indexes = new int[array.Length];
    for (int i = 0; i < indexes.Length; i++)
        indexes[i] = i;

    for (int i = 0; i < array.Length; i++)
    {
        for (int j = i + 1; j < array.Length; j++)
        {
            if (array[i] < array[j])
            {
                int m = array[j];
                array[j] = array[i];
                array[i] = m;

                m = indexes[j];
                indexes[j] = indexes[i];
                indexes[i] = m;
            }
        }
    }
    return indexes[N];
}

6 个答案:

答案 0 :(得分:26)

如果你的阵列有一个数量庞大的数字而你需要第五大数字,那么你就要排序很多你不需要的数字。

保持长度为n的递增排序序列(链表?)并不是更快,并且对于每个元素检查它是否大于第一个(按升序排列的最小值)

  • 如果更小:跳到大数组中的下一个元素
  • 如果更大:从排序数组中删除最小的第一个元素,并将较大的元素插入正确的位置,保持数组排序。

扫描完整数组后,排序序列中的第一个元素就是您要查找的元素。

大多数比较仅适用于已排序数组的第一个元素。你必须N次更改数组,N次最大数字一次。更改数组是删除第一个元素(最小的元素)并找到插入新元素的位置以保持数组的排序

  

更正:我声明数组必须更改N次是不正确的。当提供按升序排序的数组时,可以最容易地看到这一点:每个比较的数字将大于N-size数组中的最小数字,从而导致替换

答案 1 :(得分:23)

随机化快速选择算法适用于平均情况复杂度O(n)。实际上,很少有O(n ^ 2)。它使用quicksort的分区功能

答案 2 :(得分:8)

您需要使用选择算法 https://en.wikipedia.org/wiki/Selection_algorithm

这里有漂亮的幻灯片:https://c3p0demo.googlecode.com/svn/trunk/scalaDemo/script/Order_statistics.ppt 一般算法:

Select(A,n,i):
    Divide input into ⌈n/5⌉ groups of size 5.

    /* Partition on median-of-medians */
    medians = array of each group’s median.
    pivot = Select(medians, ⌈n/5⌉, ⌈n/10⌉)
    Left Array L and Right Array G = partition(A, pivot)

    /* Find ith element in L, pivot, or G */
    k = |L| + 1
    If i = k, return pivot
    If i < k, return Select(L, k-1, i)
    If i > k, return Select(G, n-k, i-k)

答案 3 :(得分:5)

你可以创建一个大小为N的堆,它具有最大的数字作为它的第一个元素(而不是通常给出的最小的一个)。然后,您将遍历整数数组,只要您的元素小于堆的最大成员,就可以将其插入堆中。如果这使得堆超过N的大小,则删除其中最大的成员。

这应该是最便宜的方法之一。具体的“第n个最大的m”算法可能会击败它,但可能不是渐近的。

答案 4 :(得分:5)

您的排序算法目前还不是最快的。你应该google for“Quicksort”获得更快,更快的算法。

在您实施Quicksort之后,您会考虑是否真的需要对整个数组进行排序。假设您想要找到10,000个数字中最大的20个,为什么要对剩余的9,980个数字进行排序?您可以轻松修改Quicksort,以便找到N个最大的数字,但大多数情况下忽略其余数字。

答案 5 :(得分:0)

也许这可以帮助某人。在 int 数组中找到第 n 个最大的数。

            int[] arr = new int[] { 3, 2, 1, 5 };
            Array.Sort(arr);
            int elemCount = 0;
            int? thirdLargestNumber = null;
            foreach (var elem in arr)
            {
                var temp = arr.Skip(elemCount).ToArray();
                if (temp.Length == 3) //replace `3` with variable.
                { 
                    thirdLargestNumber = temp[0];
                    break;
                }
                elemCount++;
            }
            Console.WriteLine($"Third largest number = {thirdLargestNumber}");