ソートされていない配列でk番目に大きい要素を見つけます。検索する必要があるのは、配列のソート後のk番目に大きい要素であり、k番目の異なる要素ではないことに注意してください。
例1:
入力:[3,2,1,5,6,4]およびk = 2
出力:5
例2:入力:[3,2,3,1,2,4,5,5,6]およびk = 4
出力:4
kは常に有効であり、1≤k≤配列の長さであると想定できます。
具体的なアイデアについては、この記事を参照してください:再帰と分割統治| 1:アルゴリズム/中央値の例を選択:油井。この記事では、K番目に小さい要素を求め、この質問ではK番目に大きい要素を求めます。小さな変更のみが必要で、考え方は同じです。
ACコードは以下に添付されています。
void swap(int a[], int i, int j) {
int t = a[i];
a[i] = a[j];
a[j] = t;
}
/* 将数组a的[s, e]范围,按照与pivot的大小关系,划分到pivot两侧 *
* 返回pivot最终的下标
* 注:pivot是随机选取的 */
int RandomizedPartition(int a[], int s, int e) {
int pivot = a[e]; //取最后一个元素为pivot来划分
int i = s, j = e - 1;
while (i < j) {
while (a[i] >= pivot && i < e - 1)
i++;
while (a[j] <= pivot && j > s)
j--;
if (i < j)
swap(a, i, j);
}
if(a[i] > pivot) //所有元素都比pivot大,原序列不需要调整
return e;
else {
swap(a, i, e); //将pivot转到合适位置
return i;
}
}
/* 找数组a[s, e]范围内的第k小元素 */
int RandomizedSelect(int a[], int s, int e, int k) {
int pivot_index = RandomizedPartition(a, s, e); //按照与pivot的大小关系,划分到pivot两侧。返回pivot最终的下标
int num = pivot_index - s + 1; //pivot(包括在内)左侧的元素个数
if (num == k)//第k小元素恰好是pivot
return a[pivot_index];
else if (k < num) //在pivot左边找
return RandomizedSelect(a, s, pivot_index - 1, k);
else //在pivot右边找
return RandomizedSelect(a, pivot_index + 1, e, k - num);
}
int findKthLargest(int* nums, int numsSize, int k){
return RandomizedSelect(nums, 0, numsSize - 1, k);
}