Problem: There is an array A [, 2,…, with the size of n ,..., N-1], where k is the largest number.
This is a classic problem. It is proposed as a separate section in the introduction to algorithms, and its solution makes good use of the idea of sub-governance, the time complexity is controlled at O (n), which is not as expected.
This problem can also be deformed as follows: there is an array of n, A [, 2 ,..., N-1], where the first k is a large number.
The word difference is that the original problem is "The k is big", and the deformation problem is "the first k is big", but the average time complexity can be controlled at O (n ), this cannot help surprise people.
First, let's analyze the original problem: there is an array A [0, 1, 2,…, with the size of n ,..., N-1], where k is the largest number.
Let's first take the special case, So k = 1, that is to take the maximum number, as long as you scan the array again, you can determine this value, if k = 2, scan the arrays on both sides to determine the second largest number, and so on. The time complexity is O (k * n). If k and n are an order of magnitude, the time complexity is O (n * n), which is obviously not the optimal solution.
The difficulty in considering the divide and conquer method lies in how to resolve this problem into two subproblems.
The most basic step for fast sorting:
Take a random number x, exchange it with the element at the end of the array, and then swap the smaller number to the front, and the larger number to the back.
This step breaks down the fast Sorting Problem of an array into the Sorting Problem of two sub-arrays. Now we can solve the problem of getting the k largest number.
Set the following table of the array to start from 0 and end with n-1.
1. Randomly fetch a number and exchange it with the elements at the end of the array.
A) idx = rand (0, n-1); generate a random number between 0 and n-1.
B) Swap (array [idx], array [n-1]);
2. Use the end element x to swap a number smaller than x to the front, a number larger than x to the back, and return the position mid of x in the array.
3. If mid = n-k, this value is returned, which is the maximum number of k.
If mid> n-k, the number of k is in the left half array, and in the left half array is the number of k-(n-mid.
If mid <n-k, the number of k is in the right array, and it is still the number of k.Copy codeThe Code is 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 indicates the position of the last element smaller than p [n-1]
Int j = 0; // j is used to scan arrays.
For (j = 0; j <n; j ++)
{
// Swap the number 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); // divide the original array
If (mid = n-k) // if mid = n-k, this value is returned, which is the number of k
Return p [mid];
Else if (mid <n-k)
Return getMaxK (p + mid + 1, n-mid-1, k); // If mid <n-k, then the number of k is in the right array, and it is still the number of k
Else
Return getMaxK (p, mid, k-(n-mid); // If mid> n-k, the number of k is in the left half array, in the left half array, the number is k-(n-mid ).
}
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;
}