Problem: There is a size of n array a[0,1,2,..., n-1], the number of which is K-large.
This problem is a classic question, in "Introduction to Algorithms" is presented as a separate section, and its solution is a good use of the idea of partition, the time complexity of control in the O (n), which is more than we expected, this is not a table.
The problem can also be deformed as follows: There is an array of n size a[0,1,2,..., n-1], and the number of the top k is obtained.
A word of the difference, the original problem is "K-big", the problem is the deformation of "K-Big", but the average time complexity can be controlled in O (n), which could not help but the people secretly amazed.
let us first analyze the original problem: there is an array of n size a[0,1,2,..., n-1], the number of which is K-large.
We take the exception first, make k=1, then take the largest number, as long as you scan the array can determine the value, if k=2, then scan both sides of the array can determine the second largest number, and so on, the time complexity is O (k*n), if K and N is an order of magnitude, then the time complexity is O (n*n) , obviously not the optimal solution.
The difficulty in considering the partition method is how to decompose the problem into two sub problems.
the most basic step in fast sorting:
Take a random number x, swap it with the end element of the array, and then swap the number smaller than it before, swapping it to the back of its larger number.
This step causes the fast sorting problem of an array to be decomposed into a sort problem of two sub arrays, and now we can solve the problem of taking the number K large.
Set array The following table starts at 0 and ends at n-1.
1. Take a random number and swap it with the end element of the array.
A) Idx=rand (0,n-1), generating random numbers between [0,n-1].
b) Swap (Array[idx], array[n-1]);
2, with the end element x, will be smaller than the number of x to the front, than the number of X to Exchange to after, and return at this time x in the array position mid.
3, if mid==n-k, then return the value, this is the number K large.
If mid>n-k, then the number k large is in the left half of the group, and in the left half of the group is K (n-mid) large number.
If the mid<n-k, then the number k large is in the right half of the group, and still is the number K.
Copy Code code as follows:
#include "iostream"
using namespace Std;
int random_partion (int *p, int n)
{
int Idx=rand ()%n;
Swap (P[idx], p[n-1]);
int i=-1; I represents the position of the last element less than p[n-1]
int j=0; J used to scan arrays
For (j=0 j<n; j + +)
{
Swap the number of less than p[n-1] to the first half
if (P[j]<p[n-1])
{
Swap (P[++i], p[j]);
}
}
Swap (P[++i], p[n-1]);
return i;
}
int getmaxk (int *p, int n, int k)
{
int mid;
if (k<=0)
return-1;
if (n<k)
return-1;
Mid=random_partion (P, N); Make a partition of the original array
if (mid = = n-k)//If mid==n-k, then return the value, which is the number k large
return P[mid];
else if (mid<n-k)
Return Getmaxk (P+mid+1, n-mid-1, K); If mid<n-k, then the number k large is in the right half of the group, and still is the number k large
Else
Return Getmaxk (P, Mid, K (N-mid)); If mid>n-k, then the number of k large is in the left half of the group, and in the left half of the group is K (n-mid) Large number
}
int main (void)
{
int num,a[] = {12012, 3, 945, 965, 66, 232, 65, 7, 8, 898, 56, 878, 170, 13, 5};
Num=getmaxk (A, 15, 4);
printf ("%d\n", num);
System ("pause");
return 0;
}