求無序陣列中最大的K個數 或 第K大的數
阿新 • • 發佈:2019-01-01
1、方法一:要求無序陣列中沒有重複元素,同時允許更改陣列內的內容。主要思想是利用快速排序Partition函式依次進行前K個元素的排序,平均時間複雜度O(n)。
#include <iostream> #include <string> #include <stack> #include <fstream> #include <sstream> #include <vector> #include <ctime> #include <exception> using namespace std; void Swap(int *a, int *b) { int tmp; tmp = *a; *a = *b; *b = tmp; } int Partition(int *arr, int len, int sIdx, int eIdx) //可以返回一個下標,該下標所對應的數組裡的數已排序好。 { if (arr == nullptr || len<=0 || sIdx<0 || eIdx>len-1) { cout << "Error occurred in Partition"; return -1; } int ii = sIdx, jj = ii+1; int pivot = arr[sIdx]; for (; jj<=eIdx; ++jj) { if (arr[jj]>pivot) { Swap(&arr[jj], &arr[++ii]); } } Swap(&arr[ii], &arr[sIdx]); return ii; } void FindKthElem(int *arr, int len, int sIdx, int eIdx, int k) { if (arr == nullptr || len<=0 || sIdx<0 || eIdx>len-1 || k<=0 || k>len) { cout << "Invalid input."; return; } if (sIdx<=eIdx) //要多加一個等號 { int midIdx = Partition(arr, len, sIdx, eIdx); if (midIdx>k-1) { FindKthElem(arr, len, sIdx, midIdx, k); } else if (midIdx<k-1) { FindKthElem(arr, len, midIdx+1, eIdx, k); } else { cout << endl; cout << "第" << k << "大的數為:"<< arr[k-1] << endl; return ; } } } int main (int argc, char ** argv) { int arr[] = {8, 3, 7, 9, 4, 0, 5, 2, 1, 6}; for(int kk=1; kk<=10; ++kk) { FindKthElem(arr, 10, 0, 9, kk); cout << "查詢後的陣列內元素:"; for (int ii=0; ii<10; ++ii) cout << arr[ii] << " "; } getchar(); getchar(); return 0; }
2、方法二。使用堆排序。(180412)
vector<int> GetMaxNumbers_Solution(vector<int> input, int k) { if (k<=0 || input.size() < k) return vector<int>(); set<int> output; for (auto it = input.begin(); it != input.end(); ++it) { if (output.size() < k) { output.insert(*it); } else { auto it2 = output.begin(); if (*it > *it2) { output.erase(it2); output.insert(*it); } } } vector<int> v1(output.begin(), output.end()); return v1; }
測試結果: