for the last few days I've been trying really hard to write this algorithm but without success. The code works and most of the time it gives me the right result but there are some cases where it fails. For example with this array {3, 8, 1, 9, 10, 7, 6, 2, 5, 4} and k = 6 it should give me 6 as result but it gives me 7. Can someone help me? I can't figure out what's the problem.
Here is the code:
class MOMSelect {
static int median(int a[], int i, int n) {
if(i <= n)
Arrays.sort(a, i, n);
else
Arrays.sort(a, n, i);
return a[n/2];
}
static int medianOfMediansSelect(int a[], int left, int right, int k) {
int n = right - left + 1;
int i;
int[] medians = new int[(n + 4) / 5];
for (i = 0; i < n/5; i++) {
medians[i] = median(a, left + i * 5, 5);
}
if (i*5 < n) {
medians[i] = median(a,left + i * 5, n % 5);
i++;
}
int medianOfMedians = (i == 1)? medians[i - 1]: median(medians, 0, medians.length);
int pivotIndex = partition(a, left, right, medianOfMedians);
if (pivotIndex == k - 1) {
return a[pivotIndex];
}
else if (pivotIndex - left > k - 1) {
return medianOfMediansSelect(a, left, pivotIndex - 1, k);
}
else {
return medianOfMediansSelect(a, pivotIndex + 1, right, k);
}
}
static void swap(int[] a, int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
static int partition(int[] a, int left, int right, int x) {
int i;
for (i = left; i < right; i++)
if (a[i] == x)
break;
swap(a, i, right);
i = left;
for (int j = left; j <= right - 1; j++) {
if(a[j] <= x) {
swap(a, i, j);
i++;
}
}
swap(a, i, right);
return i;
}
public static void main(String[] args) {
int a[] = {3, 8, 1, 9, 10, 7, 6, 2, 5, 4};
int n = a.length;
int k = 1;
System.out.println(medianOfMediansSelect(a, 0, n - 1, k));
}
}
Thanks in advance to everyone
So, I modified your median
method to correct the problem. You should check Arrays.sort
method for a clear understanding.
Now it gives 6
, for k=6
.
Here is it,
static int median(int a[], int i, int n)
{
Arrays.sort(a, i, i + n - 1);
return a[i + n / 2];
}