拿到這個題目,我們首先想到的肯定的是對數組進行排序,然后再取第K大的數。所以在這里我們先羅列兩個方法。
一,基於快排實現的。
說道排序首先想到的應該是快排,它的時間復雜度為O(NlogN),但是在這里又有一些不同,因為我們不需要度我們不關注的那一部分進行排序。
思路:根據key值把數組分割為兩半,一半數字大、一半數字小。其中這兩半有一半不是我們所要的,可以去除,只在我們需要的那一部分進行遞歸下去即可。
圖片來源:http://www.csie.ntnu.edu.tw/~u91029/index.html
下面給出基於快排實現的代碼:PS(快排部分是基於前面快排算法實現)
#include<iostream> #include<ctime> using namespace std; int result; void swap(int &a, int &b){ int temp = a; a = b; b = temp; } void qSort(int* A, int left, int right, int k){ if (A == NULL) return; if (left == right) result = A[left]; if (left < right){ int count = left; int key = A[left]; swap(A[left], A[right]); for (int i = left; i < right; ++i){ if (A[i] < key) continue; else { swap(A[count], A[i]); count++; } } swap(A[count], A[right]); if (count + 1 == k) { result = A[count]; return; } else if (count + 1 > k) qSort(A, left, count - 1, k); else if (count + 1 < k) qSort(A, count + 1, right, k); } } int main(){ const int n = 10; srand(time(0)); int a[n] = { 0 }; for (int i = 0; i < n; i++) { a[i] = (rand() % 30); cout << a[i] << " "; } cout << endl; int k; cin >> k; qSort(a, 0, n - 1, k); for (int i = 0; i != n; ++i){ cout << a[i] << " "; } cout << endl; cout << "第" << k << "大的值為:" << result << endl; return 0; }
二,通過計數排序法來實現
計數排序實現我們在前面實現過了,這里需要修改一下就是計數值和要與k比較,大於等於k是輸出他的索引值。
#include<iostream> #include<vector> using namespace std; int result; int main(){ int a[] = { 4, 6, 6, 4, 6, 4, 9, 1, 5, 6 }; int k; cin >> k; int max = -1; for (int i = 0; i != (sizeof(a) / sizeof(int)); ++i) { if (max < a[i]) max = a[i]; } vector<int> ivec(max + 1, 0); for (int i = 0; i != (sizeof(a) / sizeof(int)); ++i) { ivec[a[i]]++; } int cmp = 0; for (int i = 0; i != ivec.size(); ++i) { cmp += ivec[i]; if (cmp >= k) { result = i; break; } } cout << "第" << k << "大的數是:" << result << endl; return 0; }