bfprt
bfprt
//找第k小的数 or 找第n-k大的数 #include <iostream> #include <vector> #include <algorithm> using namespace std; class Solution { public: int getMinKByBFPRT(vector<int>& arr,int k) { if(k<0||k>arr.size()) return 0; vector<int> tmp(arr.begin(),arr.end()); return bfprt(tmp,0,tmp.size()-1,k); } private: int bfprt(vector<int>& arr,int left,int right,int k) { if(left==right) return arr[left]; //1.得到中位数 int pivot=getMedian(arr,left,right); //2.根据中位数划分左右区间 vector<int> pivotRange(_partition(arr,left,right,pivot)); //3.找到中位数排序后的位置,判断k是不是中位数所在的下标范围内,如果在就找到了 if(k>=pivotRange[0]&&k<=pivotRange[1]) return arr[k]; else if(k<pivotRange[0]) return bfprt(arr,left,pivotRange[0]-1,k); else /*if(k>pivotRange[1])*/ return bfprt(arr,pivotRange[1]+1,right,k); //return 0; } int getMedian(vector<int>& arr,int left,int right) { int nums=right-left+1; int offset=nums%5==0?0:1;//每五个为一组,求每组的中位数,放在中位数数组中 vector<int> midArr(nums/5+offset);//中位数数组 for(int i=0;i<midArr.size();++i) { int l=left+i*5; int r=l+4; midArr[i]=getMedianCore(arr,l,min(r,right)); } //找中位数组的中位数 return bfprt(midArr,0,midArr.size()-1,midArr.size()/2); } int getMedianCore(vector<int>& arr, int left, int right) { //中位数组排序,返回中间数 sort(arr.begin()+left,arr.begin()+right+1); return arr[(left+right)/2+(left+right)%2];//奇数和偶数情况 } vector<int> _partition(vector<int>& arr,int left,int right,int pivot) { int small=left-1;//small总是指向当前最小的位置,初始化为数组的首元素的前一位置 int big=right+1;//big总是指向当前最大的位置,初始化为数组的尾元素的后一位置 int cur=left; while(cur<big) { if(arr[cur]<pivot) swap(arr[++small],arr[cur++]); else if(arr[cur]>pivot) swap(arr[cur],arr[--big]); else ++cur; } vector<int> tmp{small+1,big-1}; return tmp; } }; int main() { Solution s; vector<int> arr{1}; cout<<s.getMinKByBFPRT(arr,1)<<endl; return 0; }