这道题用的是老师上课讲的最坏时间复杂度为O(n)的算法,即BFPTR算法,简单来说就是给一个数组,然后将其划分为5个一组,然后剩下的为一组,然后将其放到一个数组继续递归,直到不足五个时返回中位数,然后我们用这个中位数作为基准进行分治,将大于该数的放在右边,小于的放在左边,然后比较k和基准的位置,相同则直接输出,否则在另一边继续递归。
1 //BFPRT算法 2 void swap(vector<int> &nums,int i,int j) 3 { 4 int temp=nums[i]; 5 nums[i]=nums[j]; 6 nums[j]=temp; 7 } 8 int partion(vector<int>&nums,int l,int r,int m) 9 { 10 int s=nums[m]; 11 swap(nums,l,m); 12 int j=l; 13 for(int i=l+1;i<=r;i++) 14 { 15 if(nums[i]<s) 16 { 17 j++; 18 swap(nums,j,i); 19 } 20 } 21 swap(nums,j,l); 22 return j; 23 } 24 //找一个数在nums数组中的位置 25 int findId(vector<int> &nums,int l,int r,int val) 26 { 27 for(int i=l;i<=r;i++) 28 { 29 if(nums[i]==val) 30 return i; 31 } 32 return -1; 33 } 34 int findMedia(vector<int> &nums,int l,int r) 35 { 36 if(l==r) 37 return nums[l]; 38 int i=l; 39 int n; 40 for(i=l;i<=r-5;i+=5) 41 { 42 sort(nums.begin()+l,nums.begin()+5+l); 43 n=i-l; 44 swap(nums,l+n/5,i+2); 45 } 46 int a=r-i+1; 47 if(a>0) 48 { 49 sort(nums.begin()+i,nums.begin()+r+1); 50 n=i-l; 51 swap(nums,l+n/5,i+a/2); 52 } 53 n=n/5; 54 return findMedia(nums,l,l+n); 55 } 56 int bfptr(vector<int> &nums,int l,int r,int k) 57 { 58 int n=findMedia(nums,l,r); 59 int id=findId(nums,l,r,n); 60 int i=partion(nums,l,r,id); 61 62 int m=i-l+1; 63 if(m==k) 64 return nums[i]; 65 else if(m<k) 66 { 67 return bfptr(nums,i+1,r,k-m); 68 } 69 else 70 { 71 return bfptr(nums,l,i-1,k); 72 } 73 } 74 int findKthLargest(vector<int>& nums, int k) { 75 return bfptr(nums,0,nums.size()-1,nums.size()-k+1); 76 }