An Efficient way of randomizing an array - Shuffle code

最后都变了- 提交于 2019-12-06 08:46:48

问题


I was asked this question in an interview and I gave various solutions but the interviewer was not convinced. I am interested to find a solution. Please throw in your views :

Q: Write an efficient data structure to implement the shuffle in an ipod. It must play all the songs, each time in different random order, the same song should not be repeated. ( mostly O(n))

One solution , I thought off after the interview : I can do a randomized quick sort without recursion. Where we randomly, chose 1 pivot O(1) and then do quicksort O(n). Now songs will be sorted in some order and I play them till the end. Once it reaches the end, I will Again chose a random pivot and , repeat this process again and again.

Regards, Sethu


回答1:


Place all the songs in an array... For each element in the array swap it with a random position.




回答2:


You want the Fisher-Yates shuffle. Be aware of the implementation errors mentioned on that page, as your currently accepted answer falls foul of one.




回答3:


Well, the first linear-time solution that springs to mind:

You could make a linked list of all the songs, which would take about O(n) (given that insertions are constant time operations). Then, generate a random number, modulo the size of the list to get a random index, and remove that index and append it to a new list (both of which are constant time operations).

An insertion for each O(n) + a removal for each O(n) + a second insertion O(n). This would overall lead to a linear time solution.

Edit: I completely forgot about walking the list. So, instead, you could make the result a fixed length array. Pop the head of the linked list, assign it the random index, and populate the array.




回答4:


Nate's (edited) and Brian's algorithms are the Fisher–Yates shuffle O(n), while shuffling by sorting is O(nlogn), but may actually be faster in practice (http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#Comparison_with_other_shuffling_algorithms). Getting song shuffling wrong may have insignificant consequences, but if you are writing a shuffling algorithm for an online poker game, make sure you know what you are doing (http://www.cigital.com/news/index.php?pg=art&artid=20).




回答5:


I am a beginner, let me say a solution that strikes to mind, if anything is wrong please make me know.

Lets assume songs are stored in either singly or doubly linked list. Every time when the music player is opened pick a random number less than (any number you wish) assume k, and reverse every k nodes in the list, similarly do it twice or at max thrice (as you wish) which would take O(2n) or O(3n) time to shuffle. finally have a pointer to the last node of the list. And every time a song is listened (a node is visited) remove the node and insert it next to the last node which can be done in O(1) time. This continues till the music player is closed.

Thanks, Eager to know the correctness of the answer.




回答6:


What you want is the Fisher-Yates Shuffle. Here's an implementation in java:

public void shuffle(Song[] songs) {
    Random r = new Random();
    for(int i = 0; i < songs.length - 1; i++) {
        int swap = i + r.nextInt(songs.length-1-i);
        T temp = songs[i];
        songs[i] = songs[swap];
        songs[swap] = temp;
    }
}
/* r.nextInt(max) returns integer 0 to max-1 inclusive */

How it works is it treats the entire array as a hat and starts pulling random elements and lining them up at the front of the array. All elements after i are 'in the bucket', all elements before i are shuffled.



来源:https://stackoverflow.com/questions/4053601/an-efficient-way-of-randomizing-an-array-shuffle-code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!