ith Order Statistic
The ith order statistic of a set of n elements is the element which would be in the ith position if the set were sorted. For example, the minimum is the 1st order statistic, while the maximum is the nth order statistic.
Java example - Finding ith statistic:
1
2
3
4
5
6
7
8
| int ithOrderStatistic(int[] arr, int i) {
Arrays.sort(arr);
return arr[i-1];
}
// Find 3rd largest element
int[] arr = {5, 2, 8, 3, 9};
int thirdLargest = ithOrderStatistic(arr, arr.length - 3 + 1);
|
C++ example - Select algorithm:
1
2
3
4
5
6
7
8
9
| int select(vector<int> arr, int k) {
// Use quickselect algorithm
return selectUtil(arr, 0, arr.size()-1, k-1);
}
int selectUtil(vector<int>& arr, int low, int high, int k) {
// Partition and recursively select
return arr[k];
}
|
Python example - Kth smallest element:
1
2
3
4
5
6
7
8
9
10
11
12
13
| import random
def kth_smallest(arr, k):
# Use quickselect based on random pivot
pos = random_partition(arr, low, high)
if pos == k-1:
return arr[pos]
if pos > k-1:
return kth_smallest(arr, k, low, pos-1)
else:
return kth_smallest(arr, k, pos+1, high)
|
Order statistics provide rank-based insights into data distributions. Efficient algorithms can compute them in O(n) time.
The ith order statistic of a set is its ith-smallest element. For example, the 1st order statistic is the minimum element, and the nth order statistic is the maximum for a set of size n. Order statistics are foundational in algorithms, statistics, and data structures like heaps. Finding the ith order statistic is a well-studied problem with various algorithms, such as Quickselect, to solve it efficiently. The key takeaway is that ith order statistics provide a structured way to query sets for specific elements based on their size.
Java Code
In Java, Quickselect can be used to find the ith order statistic. The function quickSelect
is used for this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
| import java.util.Random;
public class QuickSelect {
public static int quickSelect(int[] arr, int k) {
return quickSelect(arr, 0, arr.length - 1, k - 1);
}
private static int quickSelect(int[] arr, int left, int right, int k) {
if (left == right) {
return arr[left];
}
int pivotIndex = new Random().nextInt(right - left + 1) + left;
pivotIndex = partition(arr, left, right, pivotIndex);
if (k == pivotIndex) {
return arr[k];
} else if (k < pivotIndex) {
return quickSelect(arr, left, pivotIndex - 1, k);
} else {
return quickSelect(arr, pivotIndex + 1, right, k);
}
}
private static int partition(int[] arr, int left, int right, int pivotIndex) {
int pivotValue = arr[pivotIndex];
swap(arr, pivotIndex, right);
int storeIndex = left;
for (int i = left; i < right; i++) {
if (arr[i] < pivotValue) {
swap(arr, storeIndex, i);
storeIndex++;
}
}
swap(arr, right, storeIndex);
return storeIndex;
}
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
|
quickSelect
is a wrapper function that calls a recursive function to perform Quickselect.- The
partition
function rearranges elements based on a randomly chosen pivot.
C++ Code
In C++, the Quickselect algorithm is implemented as follows:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
| #include <algorithm>
#include <random>
int quickSelect(std::vector<int>& arr, int left, int right, int k) {
if (left == right) {
return arr[left];
}
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> distr(left, right);
int pivotIndex = distr(gen);
std::swap(arr[pivotIndex], arr[right]);
int storeIndex = left;
for (int i = left; i < right; ++i) {
if (arr[i] < arr[right]) {
std::swap(arr[i], arr[storeIndex]);
storeIndex++;
}
}
std::swap(arr[right], arr[storeIndex]);
if (k == storeIndex) {
return arr[k];
} else if (k < storeIndex) {
return quickSelect(arr, left, storeIndex - 1, k);
} else {
return quickSelect(arr, storeIndex + 1, right, k);
}
}
|
- Similar to the Java version, a recursive function
quickSelect
performs the task. std::swap
is used for element swapping.
Python Code
In Python, Quickselect can be implemented as follows:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| import random
def quick_select(arr, k):
return _quick_select(arr, 0, len(arr) - 1, k - 1)
def _quick_select(arr, left, right, k):
if left == right:
return arr[left]
pivot_index = random.randint(left, right)
pivot_index = _partition(arr, left, right, pivot_index)
if k == pivot_index:
return arr[k]
elif k < pivot_index:
return _quick_select(arr, left, pivot_index - 1, k)
else:
return _quick_select(arr, pivot_index + 1, right, k)
def _partition(arr, left, right, pivot_index):
arr[pivot_index], arr[right] = arr[right], arr[pivot_index]
store_index = left
for i in range(left, right):
if arr[i] < arr[right]:
arr[store_index], arr[i] = arr[i], arr[store_index]
store_index += 1
arr[right], arr[store_index] = arr[store_index], arr[right]
return store_index
|
_quick_select
is the recursive function for Quickselect.- The
_partition
function rearranges elements, similar to the Java and C++ versions.
By understanding these implementations, you can effectively find the ith order statistic in a set of elements using Quickselect in Java, C++, and Python.