我正在尝试在大型2-D阵列中找到第N个最大元素(大约850,000个元素)。 我现在使用的方法是将其转换为1-D数组,然后使用选择排序算法并以此方式找到它,但它需要的时间太长。
有人知道找到第N个最大元素的好方法,只需查看矩阵而不对其进行排序,就像找到最大的元素一样。
答案 0 :(得分:3)
我认为这是某种家庭作业或面试问题,所以我只是为你制定步骤。
找到存储N个节点的适当结构。说X.(提示,快速搜索,插入,删除......)
在one
传递中遍历矩阵,保存的值大于X中的值,并将其保存到X,并删除X中的最小值。
最后,X的最小值是N最大值。
额外空间为O(N)
,时间为O(size of the matrix)
。
答案 1 :(得分:1)
答案 2 :(得分:0)
除非您将数据结构更改为更好的数据结构(排序数组或其他内容),否则很难不迭代数组的所有元素。
从这个stackoverflow问题(Print largest number in a 2d array - why do my code print three numbers)我得到了这段代码并将其移动到C语言:
#include<limits.h>
(...)
int twodArray[XXX][YYY];
int maxValue = INT_MIN;
int yForMaxValue, xForMaxValue;
int i = 0;
for (i = 0; i < XXX; i++) {
for (int j = 0; j < YYY; j++)
if (twodArray[i][j] > maxValue) {
maxValue = twodArray[i][j];
yForMaxValue = j;
xForMaxValue = i;
}
}
}
yForMaxValue和yForMaxValue是maxValue位置的索引。
答案 3 :(得分:0)
具有有限大小N的priority queue应该可以胜任。
将2D数组的每个元素放入队列中
O(Arraysize * log2(N))复杂度。
然后队列中的第一个元素是第N个最小元素(假设arry大小> = N)
#include <stdio.h>
#include <stdlib.h>
typedef int PriorityQueue_T;
typedef struct {
PriorityQueue_T *A;
size_t Length;
size_t Size;
} PriorityQueue;
void PriorityQueue_Remove(PriorityQueue *Q) {
if (Q->Length > 0) {
size_t Index = 0;
while (1) {
size_t Mother = Index * 2 + 1;
size_t Father = Mother + 1;
if (Mother >= Q->Length) break;
if ((Q->A[Mother] < Q->A[Father]) || (Father >= Q->Length)) {
Q->A[Index] = Q->A[Mother];
Index = Mother;
} else {
Q->A[Index] = Q->A[Father];
Index = Father;
}
}
Q->Length--;
Q->A[Index] = Q->A[Q->Length];
while (Index > 0) {
size_t Child = (Index + 1)/ 2 - 1;
if (Q->A[Index] >= Q->A[Child]) {
break;
}
PriorityQueue_T tmp = Q->A[Index];
Q->A[Index] = Q->A[Child];
Q->A[Child] = tmp;
Index = Child;
}
}
}
void PriorityQueue_Insert(PriorityQueue *Q, PriorityQueue_T x) {
if (Q->Length < Q->Size || x > Q->A[0]) {
if (Q->Length >= Q->Size) {
PriorityQueue_Remove(Q);
}
size_t Index = Q->Length++;
Q->A[Index] = x;
while (Index > 0) {
size_t Child = (Index + 1)/ 2 - 1;
if (Q->A[Index] >= Q->A[Child]) {
break;
}
PriorityQueue_T tmp = Q->A[Index];
Q->A[Index] = Q->A[Child];
Q->A[Child] = tmp;
Index = Child;
}
}
}
// Pseudo code here to end
void PQ_FindNthSmallest(PriorityQueue_T Array[W][H], size_t N) {
PriorityQueue Q;
Q.Length = 0;
Q.Size = N;
Q.A = malloc(Q.Size * sizeof(PriorityQueue_T));
For each element in the array
PriorityQueue_Insert(&Q, Array[x][y]);
printf("Nth smallest: %CorrespondingFormat", Q.A[0]);
free(Q.A);
}