【C++實現】第k大元素 時間複雜度為O(n),空間複雜度為O(1)
阿新 • • 發佈:2019-01-01
解題思路:
二基準快速排序,在排序時判斷每次找到的標記點下標 p 與 n-k 的大小,若小於n-k,則只需在p的右側繼續遞迴,若大於 p 則只需在p 的左側遞迴,直至 p 與 n-k 相等
vs可執行程式碼
#include<ctime> #include<vector> #include<iostream> #include<cassert> #include<string> using namespace std; namespace SortTestHelper { // 生成有n個元素的隨機陣列,每個元素的隨機範圍為[rangeL, rangeR] vector<int> generateRandomArray(int n, int rangeL, int rangeR) { assert(rangeL <= rangeR); vector<int> v; srand(time(NULL)); for (int i = 0; i < n; i++) v.push_back( rand() % (rangeR - rangeL) + rangeL); return v; } } class Solution { public: /* * @param n: An integer * @param nums: An array * @return: the Kth largest element */ int __partition(vector<int> &arr, int l, int r) { swap(arr[l], arr[rand() % (r - l) + l]); int e = arr[l]; int i = l + 1, j = r - 1; while (true) { while (i < r && arr[i] < e) i++; while (j > l && arr[j] > e) j--; if (i>j) break; swap(arr[i], arr[j]); i++; j--; } swap(arr[l], arr[j]); return j; } void __quickSort(vector<int> &arr, int l, int r) { if (r - l < 2) return; int p = __partition(arr, l, r); __quickSort(arr, p + 1, r); __quickSort(arr, l, p); } void quickSort(vector<int> &arr, int n)//全部排序 { srand(time(NULL)); __quickSort(arr, 0, n); } //只用於找到第k大的元素 只需下面三個函式與第一個函式即可 void __quickSortPart(vector<int> &arr, int l, int r) { if (r - l < 2) return ; int p = __partition(arr, l, r); if (p < index) __quickSortPart(arr, p + 1, r); else if (p>index) __quickSortPart(arr, l, p); else return ; } void quickSortPart(vector<int> &arr, int n) { srand(time(NULL)); __quickSortPart(arr, 0, n); } int kthLargestElement(int n, vector<int> &nums) { // write your code here int len = nums.size(); index = len - n; quickSortPart(nums, len); cout << nums[index] << endl; return nums[index]; } //判斷排序成功與否 bool isSorted(const string &sortName, vector<int>& arr, int n) { for (int i = 0; i < n - 1; i++) if (arr[i] > arr[i + 1]) { cout << sortName << "無序!" << endl; return false; } cout << sortName << "有序!" << endl; return true; } //測試排序時間 void testSort(const string &sortName, vector<int>& arr,int n) { clock_t startTime = clock(); quickSort(arr, n); clock_t endTime = clock(); assert(isSorted(sortName, arr, n)); cout << sortName << " : " << double(endTime - startTime) / CLOCKS_PER_SEC << " s" << endl; return; } private: int index; }; int main() { int n = 1000000; vector<int> &v = SortTestHelper::generateRandomArray(n, 0, n); Solution s; s.kthLargestElement(999,v);//找到第999大的數 s.testSort("Quick Sort",v,n); cout << v[n - 999];//輸出排序之後的第999大的數 cout << endl; system("pause"); return 0; }
提交程式碼 此程式碼可50ms內AC
class Solution { public: /* * @param n: An integer * @param nums: An array * @return: the Kth largest element */ int __partition(vector<int> &arr, int l, int r) { swap(arr[l], arr[rand() % (r - l) + l]); int e = arr[l]; int i = l + 1, j = r - 1; while (true) { while (i < r && arr[i] < e) i++; while (j > l && arr[j] > e) j--; if (i>j) break; swap(arr[i], arr[j]); i++; j--; } swap(arr[l], arr[j]); return j; } void __quickSortPart(vector<int> &arr, int l, int r) { if (r - l < 2) return ; int p = __partition(arr, l, r); if (p < index) __quickSortPart(arr, p + 1, r); else if (p>index) __quickSortPart(arr, l, p); else return ; } void quickSortPart(vector<int> &arr, int n) { srand(time(NULL)); __quickSortPart(arr, 0, n); } int kthLargestElement(int n, vector<int> &nums) { // write your code here int len = nums.size(); index = len - n; quickSortPart(nums, len); return nums[index]; } private: int index; };