最小的K個數

2021-07-02 20:13:26 字數 1442 閱讀 1082

從「陣列中出現次數超過一半的數字」得到啟發,同樣可以基於partition函式來解決。

一、o(n)演算法

void getleastnumbers(int *input, int n, int *output, int k)

else

}for (int i = 0; i < k; ++i)

output[i] = input[i];

}

二、o(nlogk)演算法

可以先建立乙個大小為k的資料容器來儲存最小的k個數字,姐下來我們每次從輸入的n個整數中讀入乙個數。如果容器中已有的數字少於k個,則直接把這次讀入的整數放入容器中;如果容器中已有k個數,也就是容器已滿,此時我們不能再插入新的數字而只能替換已有的數字。找出這已有的k個數的最大值,然後拿這次待插入的整數和最大值進行比較。如果待插入的值比當前已有的最大值還要大,那麼直接丟棄。

很容易想到最大堆,於是我們每次可以在o(1)得到已有的k個數字的最大值,但需要o(logk)時間完成刪除及插入操作

// 「下沉」,位置pos處開始

void sink(int pos, int a, int n)

}

// array:輸入陣列

// a[0]未用

fori = 0    to   k

a[i+1] = array[i]

end for

// 建立大根堆:將陣列中的前k個元素構建成乙個最大堆

void buildheap(int a, int k) // k個元素,完全二叉樹儲存

}

//  陣列後面的元素,往最大堆插入(待插元素比堆頂元素小) 或者  丟棄(待插元素大於堆頂元素)

fori = k + 1    to       n

ifarray[i] < a[1]

a[1] = array[i]

sink(1, a,  k)

end if

end for

二、利用stl set和multiset(允許重複)底層基於紅黑樹實現的機制

typedef multiset> intset; // 按從大到小排序

typedef multiset>::iterator setiterator;

void getleasetnumbers(const vector&data, intset &leastnumbers, int k)}}

}

最小的K個數

問題描述 給定的n個整數,計算其中最小的k個數。最直觀的解法莫過於將n個數按公升序排列後輸出前k個。但是就效率來看,這種方法並不是最理想的。一種改進方法是借助快速排序中對陣列的劃分,以第k個元素對陣列進行劃分,使得比第k個數字小的數字都在其左邊,比其大的數字都在它的右邊。void swap int ...

最小的K個數

輸入n個整數,找出其中最小的k個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,如果不讓使用sort的話,自己實現乙個,或者依次選取最小的 class solution public vectorgetleastnumbers solution vectori...

最小的K個數

輸入n個整數,找出其中最小的k個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,基本方法 思路一 在k個數的陣列中多次排序,每次替換掉最大的,直到原陣列中的數比較完 vectorgetleastnumbers solution vectorinput,int ...