1) Сортировка вставки, которая обеспечивает n свопов для n инверсионных пар.
2) Принимая цвета, которые хранятся в ведрах, существует очень большая вероятность того, что подобные цвета подходят ближе, учитывая n ковшей. Это приводит к ситуации частично отсортированного массива, где массив частично сортируется, если число инверсий < = cn
.
Есть две проблемы с этой линией рассуждений.
Первое, что число инверсий не O (n) в худшем случае. Чтобы понять, почему, представьте, что у вас есть н/ синие камешки с последующим п/ красных камешков (и без белых камешков).Затем общее число обращений составляет (n)/. (И, кроме того, судя по некоторым быстрых экспериментов я просто запустить, даже в среднем случае общее число инверсий (п)/ - до сих пор не O (п).)
Вторая проблема с этой линии рассуждений является то, что вы просили, чтобы ограничить число свопов точно п, а не O (п). Так что даже если сортировка вставки требуется только (скажем) 2 & # xFEFF; n свопов, которых все равно было бы слишком много.
2) [¶] Что такое хэш-функция хэш цвета и вставить цвета в качестве частично отсортированного массива? Нужен ли мне метод линейного зондирования?
Вставка сортировки не требует хеш-функции; и я не думаю, что вы можете построить какую-либо значимую хэш-таблицу в своем ограничении постоянного дополнительного пространства.
Скорее, вы можете просто представить три цвета, как (скажем) 0, 1 и 2.
3) Почему нам нужно дополнительное пространство, как указано в вопросе? Поскольку сортировка вставки является алгоритмом на месте
Даже для сортировки вставки требуются дополнительные переменные, например массивные индексы.
Александр Аникин уже предложил такое же решение, что я собирался предложить, но я не уверен, если это ясно из его ответа, как вы могли бы придумать что по своему усмотрению, так что остальная часть этого ответ проведет вас через это.
Итак, предположим, вы начинаете с попытки вставки сортировки. Затем мы можем улучшить его постепенно, пока он не удовлетворит требования. (Это требует наличия нескольких идей, но каждое индивидуальное улучшение требует лишь небольшого понимания, а не для решения всей проблемы сразу.)
Первое улучшение: # звонков color(i)
.
Когда мы хотим вставить новый галькой в уже отсортированную часть массива, нам нужно найти, куда он должен идти в этой части.
С чистой сортировкой вставки мы делаем это, исследуя гальки в уже отсортированной части массива. Но нам разрешено только звонить color
n раз; и мы ожидаем, что будем называть его по крайней мере один раз для каждого камешка - вы не можете сортировать камешек, не изучая его - это означает, что для выполнения этой работы нам нужно называть его ровно один раз для каждого гальки. Мы не можем позволить себе повторно вызвать его для гальки, которую мы уже отсортировали.
Чтобы исправить это, ключевое понимание состоит в том, что в уже отсортированной части массива нам действительно не нужно проверять ведро, чтобы узнать, какой цвет он имеет, если мы отслеживаем сколько гальки мы уже видели в каждом цвете. Если мы ранее видели r
красные камешки, w
белых камешков и b
голубых камешков, а затем красные камешки в ведре 0
через r-1
, белые из них находятся в r
через r+w-1
и синие в ведре r+w
через r+w+b-1
. Таким образом, мы можем выяснить, где вставить новый камешек, не называя фактически color
на любые другие гальки.
Второе усовершенствование: # звонков swap(i,j)
, часть 1.
Следующая проблема заключается в том, что с чисто сортировки вставками, вставка галечные означает «смещение» все камешки после него, что потенциально означает большое количество свопов. (Например, если мы уже видели 10 белых гальки и 5 голубых гальков, то вставка красной гальки означает «сдвиг» 15 гальки, что требует 15 своп.)
Чтобы исправить это, ключевым понятием является то, что мы на самом деле не заботятся о порядке гальки внутри цветовой группы; красная галька может прийти в любом порядке, за ней следуют белые гальки в любом порядке, за которыми следуют голубые гальки в любом порядке. Таким образом, вместо того, чтобы переместить большое количество гальки только на одну позицию, мы можем перенести одну гальку с начала цветовой группы до ее конца.
Например, если мы ранее видели r
красные камешки, w
белых камешков и b
голубых камешков, и нам нужны вставить новый красный камушек, то мы можем поменять его в положение r
(что дает нам белый камешек (если w > 0
)), затем поменяйте белый галькой в положение r+w
(давая нам синий камешек (если b > 0
)).
Это подводит нас к O (п) обменивает в худшем случае, и как раз под n
свопами в среднем случае: красная галька потребует два свопов (если w > 0
и b > 0
), белая гальки потребует один обмен (если b > 0
), а синий галька потребует нулевых свопов.
Третье улучшение: # звонков swap(i,j)
, часть 2.
Но это по-прежнему оставляет нас с потенциально слишком много свопов: если есть более красные камешки, чем синие, то мы будем (обычно) заканчиваются более чем n свопы.
Чтобы исправить это, нам понадобится последнее понимание, которое заключается в том, что мы знаем, где будут синие гальки (так как мы не заботимся о порядке, в котором они заканчиваются); поэтому вместо того, чтобы положить голубую гальку сразу после окончания уже увиденной белой гальки, мы можем положить голубые гальки на конец конца. Таким образом, нам не нужно постоянно менять диапазон синей гальки; как только синяя галька помещается, она может оставаться на месте.
Так, например, если мы уже видели r
красные камешки, w
белых камешков и b
голубых камешков, а затем красные камешки должны быть в позиции 0
через r-1
, белые камешки должны быть в позиции r
через r+w-1
, и голубые гальки должны находиться в положениях n-b
по n-1
. Положения от r+w
до n-b-1
являются пока еще несортированными.
Таким образом, наш окончательный алгоритм выглядит следующим образом:
- инициализации
r
, w
и b
к 0
.
- Инициализировать
i
до 0
.
- в то время как
i < n - b
:
- проверка
color(i)
:
- если это красный, то
swap(i, r)
и приращение r
и i
.
- если это WHITE, то просто увеличивайте
w
и i
.
- если это ГОЛУБОЙ, то
swap(i, n-b-1)
и приращение b
. Do не приращение i
(потому что галька в позиции i
- это та, которую мы только что вытащили из конца массива, которую мы еще не изучили).
(Обратите внимание, что несколько свопы могут быть устранены путем двойной проверки того, является ли две позиции поменялись местами, на самом деле разные,., Но это не требуется Мы под п свопы либо путь.)
Теперь, если бы мы начали с другого вида, а не вставки сортировки? Некоторые виды по-прежнему ведут нас в правильном направлении; например, если мы начали с сортировки в виде ведра (или рода сортировки радикса только с одной цифрой 0-2), мы все равно могли бы сделать инкрементные исправления, чтобы они закончили описанный выше алгоритм. Другие виды сортов не так хорошо выработали бы, но все же могли бы привести к полезной информации, которая помогла бы, когда мы перейдем к лучшему пути. Поэтому важно попробовать разные вещи и сохранить открытость. Чем больше вы исследуете проблему, тем больше информации вы получаете, даже если вы иногда спускаетесь по неправильному пути и должны отступать и попробовать что-то новое.
Я на смартфон прямо сейчас, и не может опубликовать правильный ответ, но - вы должны думать вне коробки. * * Стандарты * стандартных алгоритмов сортировки являются релевантными, но ни один конкретный стандартный алгоритм сортировки не удовлетворяет этим ограничениям даже по этому ограниченному вводу. (Я выложу полный ответ завтра, если меня никто не удалит.) – ruakh
@ruakh thank you, будем ждать вашего комментария – overexchange
@ruakh пожалуйста, также прокомментируйте, где я ошибся, в вашем ответе – overexchange