Eldar Shalev
Eldar Shalev

Reputation: 49

Algorithm - How to find the Kt'h element in O(K) and with build O(n)

I need to find the K element in O(k) with input of an array with an unordered n elements with the following requirements:

1) The build can be O(n) (you can build any data structure you want with the given array)

2) find the k element in O(k)

Upvotes: 3

Views: 336

Answers (1)

Paul Hankin
Paul Hankin

Reputation: 58271

This algorithm works assuming there's no repeated elements in the array.

Preprocess

Find the median element, and pivot the array on that element. Then keep applying this procedure on the smaller half of the array until you're down to a single element.

Call the larger-half of the arrays at each step A(m), A(m-1), ...., A(0) for some m. A(0) is always of size 1, and each consecutive array is either double the size of the previous array or that plus one. That is, len(A(0)) = 1, len(A(n)) = len(A(n-1)) or len(A(n-1))+1. Note that 2^n <= len(A(n)) < 2^(n+1).

Finding a median of an array of length n takes O(n) time (using a well-known linear time median finding algorithm), and pivoting also takes O(n) time. You're applying this recursively (on the smaller side), which overall takes n + n/2 + n/4 + ... = O(n) time.

Finding the k'th element

Define S(n) to be the sum of lengths of A(0), A(1), ..., A(n-1). (S(0) = 0).

Find n such that S(n) <= k, and S(n+1) > k. You can do this in O(log k) time.

Then, find the k-S(n) largest element in A(n). This can be done in O(len(A(n))) time using the (deterministic variant of the) quickselect algorithm. Since len(A(n)) is Theta(k), this element has been found in O(log k) + O(k) = O(k) time.

Note for understanding

It's easier to first consider the case where n is a power of 2 minus 1. Then the subarrays A(i) double in size. For example when n is 16, and the input is the numbers 0 to 15 in some order, the subarrays might look like this:

A(0) = [0]
A(1) = [2, 1]
A(2) = [6, 3, 4, 5]
A(3) = [15, 8, 11, 10, 7, 12, 13, 9, 14]

To find the 7th largest element, we find it must lie in A(2) and there's 3 elements combined in A(0) and A(1), so we need to find the 7-3 = 4th largest element in A(2). This we do using quickselect.

Upvotes: 3

Related Questions