#arrays #algorithm #median
#массивы #алгоритм #медиана
Вопрос:
У меня есть задание найти медиану в 4 индивидуально отсортированных массивах.
Медиана определяется как элемент, который находится в середине массива (на нижнем уровне индекса (N / 2))
Требования:
- временная сложность: линейна размеру объединенного массива
- сложность пространства: O (1)
Я знаю, как найти медиану в 2 отсортированных массивах с O (1) пробелом и O (logn) временем, но я не могу найти хорошее решение для 4 массивов, которое удовлетворяло бы требованию O (1) пробела.
Я пытался настроить алгоритм для 3 массивов, но у меня это сработало не очень хорошо.
пример для моего задания:
A = {1 5 10 15 20}
B = {2 3 4 6 7}
C = {25 30 35 40 45}
D = {8 9 90 100 145}
median(A,B,C,D) = 10
Заранее спасибо
Комментарии:
1. Чем это отличается от поиска медианы в двух (индивидуально) отсортированных массивах с O (1) пробелом ? Пожалуйста, набросайте решение для последнего и в чем заключается ваша трудность в применении его к варианту с k массивами.
2. ( Если массивы имеют сильно различающуюся длину, задача становится немного сложнее.)
3. Во что бы то ни стало обрисуйте свой
3 arrays
подход в вопросе.
Ответ №1:
Подумайте об одном несортированном массиве
Подумайте о том, чтобы рассматривать 4 массива как единый несортированный массив, разбитый на 4 части. Если вы можете изменить массивы, вы можете отсортировать все 4 массива как 1, поменяв местами значения между ними (можно выполнить некоторую оптимизацию, поскольку вы знаете, что 4 массива отсортированы). Как только вы отсортируете массивы с точностью до n / 2 (где n — совокупная длина 4 массивов), просто верните среднее значение для всех 4.
Некоторый код
Приведенная ниже реализация позволяет нескольким массивам функционировать как одному. Я реализовал методы get
, set
и length
, являющиеся основой для любого массива. Все, что нужно сделать сейчас, это отсортировать данные класса (возможно, до n / 2) с помощью get(int)
, set(int,int)
и length()
, а также метода, который возвращает медианное значение median()
.
Возможно, есть способ получить медианное значение массива за один проход, однако я не могу его придумать. Быстрая сортировка и поиск будут выполняться за O (nLogn) время сложности, только один проход уменьшит это до O (n) (линейно по отношению к размеру массива).
Также есть место для дальнейшей оптимизации путем сортировки только до n / 2 в рамках метода медианы, также при кэшировании (i, j) пар для каждого элемента при этом.
int median( int[] a1, int[] a2, int[] a3, int[] a4 ) {
MultiIntArray array = new MultiIntArray( a1, a2, a3, a4 );
array.sort();
return array.get( array.length() / 2 );
}
public class MultiIntArray {
private int[][] data;
public MultiIntArray( int[]... data ) {
this.data = data;
}
public void sort() {
// FOR YOU TO IMPLEMENT
}
public int length() {
int length = 0;
for ( int[] array : data ) {
length = array.length;
}
return length;
}
public int get( int index ) {
int i = 0;
while ( index >= data[i].length ) {
index -= data[i].length;
i = 1;
}
return data[i][index];
}
public void set( int index, int value ) {
int i = 0;
while ( index >= data[i].length ) {
index -= data[i].length;
i = 1;
}
data[i][index] = value;
}
}
Ответ №2:
С ограничением «временная сложность равна размеру объединенных массивов» это тривиально, вы просто выбираете наименьший из первых элементов четырех массивов n / 2 раза. Не требуется никакого умного алгоритма.
Я уверен, что вы можете сделать это значительно быстрее.
Комментарии:
1. Тогда вы получите наименьший из 4 массивов, а не медиану.