我想要一个更快的函数来在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];
}
答案 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}");