找出數組中第K大的數

問題:找出數組中第K大的數(類似:找出一個數組中個數超過一半的數,就是找第n/2(n爲數組長度)大的數)

解法思路:

設數組A[0,1.....n-1]

      1、隨機選擇數組中的一個數,將該數與A[n-1]交換

2、遍歷數組,遇到比A[n-1]小的就依次放在數組的最前面(遍歷到第一個比A[n-1]小的放在A[0],第二個比A[n-1]小的放在A[1]....)

3、遍歷完(一遍),即可找到隨機選取的數是第幾大的。

以上三步代碼實現:

//返回i,是值p[i]是數組中第i+1大的數
int random_partition(int *p, int n){
	int i = -1,j=0;
	int idx = rand() % n;
	swap(p[idx], p[n - 1]);
	for (j = 0; j < n; j++){
		if (p[j] < p[n - 1]){
			swap(p[++i],p[j]);
		}
	}
	swap(p[++i], p[n - 1]);
	return i;
}
4、已經找到第i+1大的數 ,剩下的就是拿i+1跟k比較

int getMaxK(int *p, int n, int k){
	int midx;
	if (k <= 0 || k > n)
		return -1;
	midx = random_partition(p,n);
	if (midx + 1 == k)
		return p[midx];
	else if (midx + 1>k)
		return getMaxK(p, midx + 1, k);
	else if (midx + 1 < k)
		return getMaxK(p+midx+1,n-midx-1,k-midx-1);
}

測試:

<pre name="code" class="cpp"><pre name="code" class="cpp">void main(){
	//找數組中個數大於一半的數
	int a[11] = {1,2,3,2,3,3,5,3,7,3,3};
	printArr(a,11);
	cout << findVal(a, 11) << endl;
	cout << getMaxK(a, 11, 11 / 2) << endl;

	//找數組中第K大的數
/*	int num, a[] = { 12012, 3, 945, 965, 66, 232, 65, 7, 8, 898, 56, 878, 170, 13, 5 };
	cout << getMaxK(a, 15, 2) << endl;
	cout << getMaxK(a, 15, 15) << endl;
	cout << getMaxK(a, 15, 14) << endl;
	*/
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章