Вы можете найти медиану, найдя среднее между вторым (n / 2) -ым самым большим элементом и минимальным (n / 2) -ым элементом.Это можно сделать с помощью этого предыдущего вопроса SO .
После этого просто выполните итерацию по вашему массиву, поместив элементы, большие, чем медиана, в один и ниже, чем медиана, в другой.
В качестве альтернативы, если вы знали размер вашей последовательности, вы могли бы создать две коллекции размера пола (n / 2): одну «наименьшую половину» ( S ) и одну«наибольшая половина» ( L ), а затем один за другим:
- Выньте один элемент из вашей последовательности, назовите его e .
- Поместите его в S , если S не заполнен.
- Если S заполнен, найдите самый большой элемент ( S | e ) (объединение двух) (это может быть реализовано путем итерации по S , пока элемент не станет больше e найден, если ничего не найдено, это e , иначе это найденный элемент) и добавьте его к L .Если это наибольшее значение было в S , введите e в S для его повторного заполнения.
- Если L полное, найдите наименьший элемент ( L | e ) и удалите его, добавив e в L , если e не было удалено.
Я считаю это время O (n);кто-то поправит меня, если я ошибаюсь.Наихудший сценарий, который я могу себе представить, это исходная последовательность, отсортированная по убыванию.
ruby-реализация (с большим количеством ярлыков неработоспособности):
def split_into_halves to_split
s = []
l = []
medianlimit = to_split.size/2
for e in to_split
if s.size < medianlimit
s.push(e)
else
if s.max >= n
max = s.max
s.delete max
s.push(e)
else
max = e
end
if l.size < medianlimit
l.push(max)
elsif l.max >= max
l.delete l.max
l.push(max)
end
end
end
return [s,l]
end
k = [2,3,6,7,1,4,5]
split_into_halves(k) #=> [[2,3,1],[6,4,5]]