2010-10-29 7 views
3

Мне задали этот вопрос в интервью, и я дал различные решения, но интервьюер не был убежден. Мне интересно найти решение. Пожалуйста, введите ваше мнение:Эффективный способ рандомизации массива - Случайный код

Q: Напишите эффективную структуру данных для реализации тасования в ipod. Он должен воспроизводить все песни, каждый раз в разных случайных порядках, одну и ту же песню не следует повторять. (в основном O (n))

Одно решение, я подумал после интервью: я могу сделать рандомизированный быстрый сортировку без рекурсии. Где мы случайным образом, выбрали 1 pivot O (1), а затем выполните quicksort O (n). Теперь песни будут отсортированы в определенном порядке, и я буду играть их до конца. Как только он достигнет конца, я снова выберу случайный стержень и повторю этот процесс снова и снова.

С уважением, Sethu

ответ

3

Поместите все песни в массиве ... Для каждого элемента в массиве поменять его случайное положение.

+0

Но в этом случае шансы повторения песен высоки? – sethu

+0

@sethu: Нет, если вы меняете его. Как изменить ABCD на CBAD. Каждый своп просто изменяет его на другую перестановку исходных элементов. –

+5

Это неверно. Это не приводит к случайной перестановке. Эта ошибка довольно распространена и описана в википедии: http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#Implementation_errors – Dijkstra

1

Ну, первое линейное время решение, которое приходит на ум:

Вы могли бы сделать связный список всех песен, которые будут принимать около O (п) (при условии, что вставки постоянные операции времени). Затем создайте случайное число по модулю размера списка, чтобы получить случайный индекс, и удалите этот индекс и добавьте его в новый список (оба из которых являются операциями с постоянным временем).

Вставка для каждого O (n) + удаления для каждого O (n) + вторая вставка O (n). Это в целом приведет к линейному временному решению.

Редактировать: Я полностью забыл про ходят по списку. Таким образом, вместо этого вы можете сделать результат массивом с фиксированной длиной. Поместите заголовок связанного списка, присвойте ему случайный индекс и заполните массив.

+0

Довольно многое, что я собирался предложить. С списками C# вы получаете 'RemoveAt', который делает удаление и усадку для вас (неприменимо к iPod, но ...) – ChrisF

+1

Удаление элемента по определенному индексу в связанном списке НЕ является постоянным временем. Фактическое удаление элемента (что означает просто удаление указателей на/из него и освобождение памяти) - O (1), но поскольку вам сначала нужно перейти к этому элементу, это O (n) для наихудшего случая. –

+0

Здесь мы должны убедиться, что случайное число, которое мы выбираем, не повторяется. Я столкнулся с той же проблемой, у вас есть какое-то решение для этого? – sethu

1

Nate's (отредактированный) и алгоритмы Брайана - это перетасовка Fisher-Yates O (n), а перетасовка путем сортировки - O (nlogn), но на самом деле может быть на практике быстрее (http://en.wikipedia.org/ вики/Fisher% E2% 80% 93Yates_shuffle # Comparison_with_other_shuffling_algorithms). Неправильное воспроизведение песни может иметь незначительные последствия, но если вы пишете алгоритм перетасовки для онлайн-игры в покер, убедитесь, что вы знаете, что вы делаете (http://www.cigital.com/news/index.php?pg= art & artid = 20).

8

Вы хотите Fisher-Yates shuffle. Помните об ошибках реализации, упомянутых на этой странице, поскольку ваш принятый в настоящее время ответ не соответствует одному.

0

Я новичок, позвольте мне сказать решение, которое приходит на ум, если что-то не так, пожалуйста, сообщите мне об этом.

Предположим, что песни хранятся в одном или двух связанных списках. Каждый раз, когда музыкальный плеер открывается, выбирайте случайное число меньше, чем (любое число, которое вы хотите), предположите k, и отбрасывайте все k узлов в списке, аналогично делайте это дважды или в три раза (как вы пожелаете), которые будут принимать O (2n) или O (3n) для перетасовки. , наконец, имеют указатель на последний узел списка. И каждый раз, когда прослушивается песня (узел посещается), удалите узел и вставьте его рядом с последним узлом, который можно выполнить в O (1) раз. Это продолжается до тех пор, пока музыкальный плеер не будет закрыт.

Спасибо, Желаем знать правильность ответа.

 Смежные вопросы

  • Нет связанных вопросов^_^