POJ2623 - Sequence Median - 寻找第K数算法

输入n个数(n <= 250000),求中值,保留一位小数

此题用sort直接能过,自己写了个寻找第K数的随机化算法,懂快排的应该都能看懂

//Memory Time
//1232K	157MS

#include<iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
using namespace std;

int findK(int* array, int left, int right, int K);

int num[250100];

int main()
{
	srand((unsigned)time(NULL));
	
	int length;
	scanf("%d", &length);
	for(int i = 0; i < length; i++ )
	{
		scanf("%d", &num[i]);
	} 
	
	if(length%2 == 1)
	{
		int temp = findK(num, 0, length-1, (length-1)/2);
		cout << temp << ".0"; 
	}
	else
	{
		int temp1 = findK(num, 0, length-1, (length-1)/2);
		int temp2 = findK(num, 0, length-1, (length-1)/2 + 1);
		
		int temp3 = temp1/2 + temp2/2;
		int temp4 = temp1%2 + temp2%2;
		if( temp4 == 1 )
			cout << temp3 << ".5";
		else
			cout << temp3 + temp4/2 << ".0";
	}
	
	return 0;
} 

int findK(int* array, int left, int right, int K)
{
	int lastLeft = left;
	int lastRight = right;
	
	float i = rand() / RAND_MAX; 
	int mid = left + (right - left) * i; 
	int tempMid = array[mid];
	array[mid] = array[left];
	array[left] = tempMid;
	left++;
	
	while(left <= right)
	{
		while(array[right] > tempMid) right--;
		while(array[left] < tempMid && left <= right) left++;
		if(left <= right)
		{
			int temp = array[right];
			array[right] = array[left];
			array[left] = temp;
			left++;
			right--;
		}
	}

	
	if(lastLeft + K == right)
	{
		return array[lastLeft];
	}
	if(lastLeft + K > right)
	{
		return findK(array, left, lastRight, lastLeft + K - left);
	}
	if(lastLeft + K < right)
	{
		return findK(array, lastLeft + 1, right , K );
	}
}

点赞