有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数。
给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在。
测试样例:
[1,3,5,2,2],5,3
返回:2
投机取巧能通过:
1 class Finder { 2 public: 3 int findKth(vector<int> a, int n, int K) { 4 // write code here 5 sort(a.begin(), a.end()); 6 return a[n - K]; 7 } 8 };
用快排思想:
1 #include <iostream> 2 #include <vector> 3 #include <string> 4 #include <queue> 5 #include <stack> 6 #include <unordered_map> 7 #include <map> 8 #include <algorithm> 9 using namespace std; 10 11 //用快排的思想:例如找49个元素里面第24大的元素,那么按如下步骤: 12 //1.进行一次快排(将大的元素放在前半段,小的元素放在后半段), 假设得到的中轴为p 13 //2.判断 p - low == k -1,如果成立,直接输出a[p],(因为前半段有k - 1个大于a[p]的元素,故a[p]为第K大的元素) 14 //3.如果 p - low > k-1, 则第k大的元素在前半段,此时更新high = p - 1,继续进行步骤1 15 //4.如果 p - low < k-1, 则第k大的元素在后半段,此时更新low = p + 1, 且 k = k - (p - low + 1),继续步骤1. 16 //由于常规快排要得到整体有序的数组,而此方法每次可以去掉“一半”的元素,故实际的复杂度不是o(nlgn), 而是o(n)。 17 class Finder { 18 public: 19 int partation(vector<int>& a, int low, int high) { 20 int key = a[low]; 21 while (low < high) { 22 while (low < high && a[high] <= key) 23 high--; 24 a[low] = a[high]; 25 while (low < high && a[low] >= key) 26 low++; 27 a[high] = a[low]; 28 } 29 a[low] = key; 30 return low; 31 } 32 int findKth(vector<int>& a, int low, int high, int k) 33 { 34 int part = partation(a, low, high); 35 if (k == part - low + 1) 36 return a[part]; 37 else if (k > part - low + 1) 38 return findKth(a, part + 1, high, k - part + low - 1); 39 else 40 return findKth(a, low, part - 1, k); 41 42 } 43 int findKth(vector<int> a, int n, int K) { 44 // write code here 45 return findKth(a, 0, n - 1, K); 46 } 47 }; 48 49 50 //测试 51 int main() 52 { 53 vector<int> v{ 1,3,5,2,2 }; 54 Finder solution; 55 cout<<solution.findKth(v, 5, 3); 56 }
时间: 2024-10-05 18:34:21