在求一个list中第K大的数的时候,可以先排序,再提取,但复杂度有nlogn,当然也可以像求取top K一样,利用堆排序或选择排序或者冒泡排序,但对堆排序而言有KlogN,其他的两个分别为KN,如果利用快速排序改进的话,时间复杂度可以降到N级别。
思路:
每次做完partition之后,统计大于基准值的元素个数n,如果n>k,则在较大的一侧中继续寻找Kth value,否则在较小的一侧寻找 k-n th value。复杂度约等于 n+n/2+n/4+..+1 为 N级别。
算法实现:
class Solution{
public:
int get_k_val(vector<int> & data_list, int k){
int low = 0;
int high = data_list.size() - 1;
int k_val = get_k_in_range(data_list, low, high, k);
return k_val;
}
int get_k_in_range(vector<int> &data_list, int low, int high,int k){
if (low >= high){
return data_list[low];
}
int mid = partition(data_list, low, high);
if (high - mid + 1 > k){
return get_k_in_range(data_list, mid+1, high, k);
}
else if(high-mid+1<k){
return get_k_in_range(data_list, low, mid - 1, k - (high - mid + 1));
}
else{
return data_list[mid];
}
}
int partition(vector<int> &data_list, int low, int high){
int flag_val = data_list[low];
int i = low;
int j = high + 1;
while (1){
while (data_list[++i] < flag_val){ if (i>=high) break; }
while (data_list[--j] > flag_val){ if (j <= low) break; }
if (i >= j){
break;
}
int temp = data_list[j];
data_list[j] = data_list[i];
data_list[i] = temp;
}
data_list[low] = data_list[j];
data_list[j] = flag_val;
return j;
}
};