一意の要素を含む配列があります。配列内の最初の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;
}
誰かがより複雑でないより良い解決策を思い付くことができれば、私は非常に感謝します。そして、元の配列を変更するつもりはありません!!
選択アルゴリズム を使用して、k番目に大きい要素を見つけます。
次に、配列を反復処理して、それより大きい/等しいすべての要素を見つけます。
複雑さ:O(n)選択用、O(n)用反復するので、合計もO(n)です。
n最大の要素を選択する通常のトリックは、最小優先度キューを維持することです。
総複雑度:O(N log n)ここで、Nは配列内の要素の総数です。
実装の詳細は演習としてお任せします(最初のステップは、優先度付きキューについて学び、実装することです)。
要素が範囲内の整数(または任意の整数型)である場合、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" );
これを解決するには、ヒープ(maxHeap)を使用した優先度付きキューを使用できます。ヒープをn回実行して、最初のn個の最大要素を取得します。各ヒープ操作にはO(log N)時間がかかるため、N個のヒープ操作はO(N log N)時間になります。
クイックソートの修正バージョンを使用します。配列全体を実際にソートする必要はありません。ピボット値よりも大きいN個の要素を分割するだけで済みます。詳細については、「アルゴリズムの概要」を参照してください。
私はこれを信じていませんが、O(n)でそれからヒープを作成することもできます。次に、ルートkを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);
}
}
@AlexandreCに従ってこれを試しました。
これにより、無制限の入力の上位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