我有一个包含唯一元素的数组。我需要以尽可能最小的复杂性找出数组中的前n个最大元素。到目前为止,我能想到的解决方案具有O(n ^ 2)的复杂性。
int A[]={1,2,3,8,7,5,3,4,6};
int max=0;
int i,j;
int B[4]={0,0,0,0,};//where n=4;
for(i=0;i<A.length();i++)
{
if(A[i]>max)
max=A[i];
}
B[0]=max;
for(i=1;i<n;i++){
max=0;
for(j=0;j<A.length();j++){
if(A[j]>max&&A[j]<B[i-1])
max=A[j];
}
B[i]=max;
}
如果有人能想出一个更复杂的更好的解决方案,我将非常感激。而且我不打算改变原来的阵列!!
答案 0 :(得分:30)
使用selection algorithm找到第k个最大元素。
接下来,迭代数组并找到所有大于/等于它的元素。
复杂性: O(n)用于选择,O(n)用于迭代,因此总数也是O(n)
答案 1 :(得分:11)
选择 n 最大元素的常用技巧是维护最小优先级队列。
总复杂度:O(N log n)其中N是数组中元素的总数。
我作为练习留给您实施细节(第一步是了解优先级队列,并实施一个)。
答案 2 :(得分:2)
如果元素是一个范围内的整数(或任何整数类型),则可以在O(n)中执行此操作,i到k包括k> = i。使用此约束,您可以对此应用“桶排序”。
这个想法非常简单。分配k - i + 1桶。现在,遍历您的集合并为该整数增加存储桶。然后,最后,您可以通过创建找到的整数(即桶号)来“重新创建”排序列表。
例如,
int collection[] = { 10, 4, 7, 1, 9, 0, 12 }; // maximum value to expect is 12, minimum is 0
int buckets[ 13 ] = { 0 };
for( int i = 0; i < 13; i++ )
{
int n = collection[ i ];
buckets[ n ]++;
}
// the first n largest elements (n = 4)
for( int j = 12; j >= 12 - 4; j-- )
{
int n = buckets[ j ];
while( n > 0 )
{
printf( "%d ", j );
n--;
}
}
printf( "\n" );
答案 3 :(得分:1)
使用Quick Sort的修改版本。您不需要对整个数组进行实际排序。您只需要分割大于枢轴值的N个元素。有关更多信息,请阅读算法简介。
答案 4 :(得分:1)
您可以使用Heap(maxHeap)来使用优先级队列来解决此问题。执行堆n次以获得前n个最大元素。每个堆操作都需要O(log N)时间,因此N堆操作将导致O(N log N)时间。
答案 5 :(得分:0)
我不相信这一点,但你也可以在O(n)中创建一个堆。然后只需删除根k次,并将堆堆积为k个最大数。 通过这种方式,对于每个最大数字,它将花费您log(n)。
public class HeapSort1{
public static void main(String args[]){
int[] array={5,75,1,5,4,1,2,4,8,4,2,15,4,2,1,5,779,9,1};
int heapsize=array.length-1;
for(int i=heapsize/2;i>=0;i--){
maxHeapify(array,i,heapsize);
}
for(int i=heapsize;i>0;i--){
array[i]=array[0]+array[i];
array[0]=array[i]-array[0];
array[i]=array[i]-array[0];
maxHeapify(array,0,--heapsize);
}
printArray(array);
}
public static void maxHeapify(int[] array,int i,int heapsize){
int largest=i;
int left=2*i+1;
int right=2*i+2;
if(left<=heapsize && array[left]>array[i]){
largest=left;
}
if(right<=heapsize && array[right]>array[largest]){
largest=right;
}
if(largest!=i){
array[i]=array[largest]+array[i];
array[largest]=array[i]-array[largest];
array[i]=array[i]-array[largest];
maxHeapify(array,largest,heapsize);
}
}
public static void printArray(int[] array){
System.out.print("\n [");
for(int i=0;i<array.length;i++){
System.out.print(array[i]+" ");
}
System.out.print("] \n");
}
public static int getMax(){
int max=array[0];
array[0]=array[heapsize];
maxHeapify(array,0,--heapsize);
}
}
答案 6 :(得分:0)
我根据@Alexandre C尝试过此操作。
这将获得无限制输入的前10个项目。处理完输入中的20个项目后便会中断。
import random
import time
top_10_items = []
cnt = 1
while True:
rand = random.randint(1,100)
print(rand)
time.sleep(1)
if len(top_10_items) !=10:
top_10_items.append(rand)
else:
m = min(top_10_items)
if rand > m:
top_10_items.append(rand)
top_10_items.remove(m)
print(top_10_items)
cnt+=1
if cnt==20:
break
答案 7 :(得分:-4)
//finding the bigest number in the array//
double big = x[0];
for(t=0;t<x[t];t++)
{
if(x[t]>big)
{
big=x[t];
}
}
printf("\nThe bigest number is %0.2lf \n",big);