Random 在音乐播放器中实现洗牌功能

Random 在音乐播放器中实现洗牌功能,random,Random,这是在一次采访中被问到的 "What is the most efficient way to implement a shuffle function in a music player to play random songs without repetition" 我建议使用链接列表方法,即使用链接列表,生成一个随机数,并从列表中删除该项目/歌曲(这样,我们可以确保没有歌曲重复) 然后我建议采用位向量法,但他一点也不满意。 那么您认为实现这样一个功能的最佳方法是什么呢?

这是在一次采访中被问到的

    "What is the most efficient way to implement a shuffle function in a music
     player to play random songs without repetition"
我建议使用链接列表方法,即使用链接列表,生成一个随机数,并从列表中删除该项目/歌曲(这样,我们可以确保没有歌曲重复)

然后我建议采用位向量法,但他一点也不满意。

那么您认为实现这样一个功能的最佳方法是什么呢?

没有完美的答案,我想这类问题旨在展开讨论。很可能是你的面试官想听的

以下是wiki的简要概述:

  • 记下从1到N的数字
  • 在1和剩余(含)的未固定数之间选择一个随机数k
  • 从低端开始计数,划掉尚未划掉的第k个数字,并将其记在其他地方
  • 从步骤2开始重复,直到删除所有数字
  • 步骤3中记录的数字序列现在是原始数字的随机排列

  • 您应该提到它的低效性和好处,如何改进它,插入几行代码,并讨论您将如何测试这些代码。

    没有完美的答案,我想这类问题旨在开始讨论。很可能是你的面试官想听的

    以下是wiki的简要概述:

  • 记下从1到N的数字
  • 在1和剩余(含)的未固定数之间选择一个随机数k
  • 从低端开始计数,划掉尚未划掉的第k个数字,并将其记在其他地方
  • 从步骤2开始重复,直到删除所有数字
  • 步骤3中记录的数字序列现在是原始数字的随机排列

  • 您应该提到它的低效性和好处,如何改进它,插入几行代码,并讨论您将如何测试这些代码。

    没有完美的答案,我想这类问题旨在开始讨论。很可能是你的面试官想听的

    以下是wiki的简要概述:

  • 记下从1到N的数字
  • 在1和剩余(含)的未固定数之间选择一个随机数k
  • 从低端开始计数,划掉尚未划掉的第k个数字,并将其记在其他地方
  • 从步骤2开始重复,直到删除所有数字
  • 步骤3中记录的数字序列现在是原始数字的随机排列

  • 您应该提到它的低效性和好处,如何改进它,插入几行代码,并讨论您将如何测试这些代码。

    没有完美的答案,我想这类问题旨在开始讨论。很可能是你的面试官想听的

    以下是wiki的简要概述:

  • 记下从1到N的数字
  • 在1和剩余(含)的未固定数之间选择一个随机数k
  • 从低端开始计数,划掉尚未划掉的第k个数字,并将其记在其他地方
  • 从步骤2开始重复,直到删除所有数字
  • 步骤3中记录的数字序列现在是原始数字的随机排列

  • 您应该提到它的低效性和好处,如何改进它,插入几行代码,并讨论您将如何测试这些代码。

    下面是一些实现。我在面试中也遇到了困难,但面试后我发现解决办法很简单

    public class MusicTrackProgram {
    
    // O(n)  in-place swapping
    public static List<MusicTrack> shuffle3(List<MusicTrack> input) {
    
        Random random = new Random();
    
        int last = input.size() - 1;
    
        while (last >= 0) {
    
            int randomInt = Math.abs(random.nextInt() % input.size());
    
            // O(1)
            MusicTrack randomTrack = input.get(randomInt);
    
            MusicTrack temp = input.get(last);
    
            // O(1)
            input.set(last, randomTrack);
            input.set(randomInt, temp);
    
            --last;
    
        }
    
        return input;
    
    }
    
    // O(n)  but extra field
    public static List<MusicTrack> shuffle(List<MusicTrack> input) {
    
        List<MusicTrack> result = new ArrayList<>();
    
        Random random = new Random();
    
        while (result.size() != input.size()) {
    
            int randomInt = Math.abs(random.nextInt() % input.size());
    
            // O(1)
            MusicTrack randomTrack = input.get(randomInt);
    
            if (randomTrack.isUsed) {
                continue;
            }
    
            // O(1)
            result.add(randomTrack);
            randomTrack.isUsed = true;
    
        }
    
        return result;
    
    }
    
    // very inefficient O(n^2)
    public static List<MusicTrack> shuffle2(List<MusicTrack> input) {
    
        List<MusicTrack> result = new ArrayList<>();
    
        Random random = new Random();
    
        while (result.size() != input.size()) {
    
            int randomInt = Math.abs(random.nextInt() % input.size());
    
            // O(1)
            MusicTrack randomTrack = input.get(randomInt);
    
            // O(1)
            result.add(randomTrack);
    
            // O(n)
            input.remove(randomTrack);
        }
    
        return result;
    
    }
    
    
    public static void main(String[] args) {
    
        List<MusicTrack> musicTracks = MusicTrackFactory.generate(1000000);
    
        List<MusicTrack> result = shuffle3(musicTracks);
    
        result.stream().forEach(x -> System.out.println(x.getName()));
    }
    
    公共类MusicTrack程序{
    //O(n)就地交换
    公共静态列表shuffle3(列表输入){
    随机=新随机();
    int last=input.size()-1;
    而(最后>=0){
    int randomInt=Math.abs(random.nextInt()%input.size());
    //O(1)
    MusicTrack randomTrack=input.get(randomInt);
    MusicTrack temp=输入。获取(最后一次);
    //O(1)
    输入。设置(最后一个,随机轨道);
    输入设置(随机点、温度);
    --最后;
    }
    返回输入;
    }
    //O(n)但额外字段
    公共静态列表洗牌(列表输入){
    列表结果=新建ArrayList();
    随机=新随机();
    while(result.size()!=input.size()){
    int randomInt=Math.abs(random.nextInt()%input.size());
    //O(1)
    MusicTrack randomTrack=input.get(randomInt);
    if(randomTrack.isUsed){
    继续;
    }
    //O(1)
    结果。添加(随机跟踪);
    randomTrack.isUsed=true;
    }
    返回结果;
    }
    //非常低效的O(n^2)
    公共静态列表shuffle2(列表输入){
    列表结果=新建ArrayList();
    随机=新随机();
    while(result.size()!=input.size()){
    int randomInt=Math.abs(random.nextInt()%input.size());
    //O(1)
    MusicTrack randomTrack=input.get(randomInt);
    //O(1)
    结果。添加(随机跟踪);
    //O(n)
    输入。删除(随机轨道);
    }
    返回结果;
    }
    公共静态void main(字符串[]args){
    列出musicTracks=MusicTrackFactory.generate(1000000);
    列表结果=shuffle3(musicTracks);
    result.stream().forEach(x->System.out.println(x.getName());
    }
    

    }下面是一些实现。我在面试中也遇到了困难,但面试后我发现解决办法很简单

    public class MusicTrackProgram {
    
    // O(n)  in-place swapping
    public static List<MusicTrack> shuffle3(List<MusicTrack> input) {
    
        Random random = new Random();
    
        int last = input.size() - 1;
    
        while (last >= 0) {
    
            int randomInt = Math.abs(random.nextInt() % input.size());
    
            // O(1)
            MusicTrack randomTrack = input.get(randomInt);
    
            MusicTrack temp = input.get(last);
    
            // O(1)
            input.set(last, randomTrack);
            input.set(randomInt, temp);
    
            --last;
    
        }
    
        return input;
    
    }
    
    // O(n)  but extra field
    public static List<MusicTrack> shuffle(List<MusicTrack> input) {
    
        List<MusicTrack> result = new ArrayList<>();
    
        Random random = new Random();
    
        while (result.size() != input.size()) {
    
            int randomInt = Math.abs(random.nextInt() % input.size());
    
            // O(1)
            MusicTrack randomTrack = input.get(randomInt);
    
            if (randomTrack.isUsed) {
                continue;
            }
    
            // O(1)
            result.add(randomTrack);
            randomTrack.isUsed = true;
    
        }
    
        return result;
    
    }
    
    // very inefficient O(n^2)
    public static List<MusicTrack> shuffle2(List<MusicTrack> input) {
    
        List<MusicTrack> result = new ArrayList<>();
    
        Random random = new Random();
    
        while (result.size() != input.size()) {
    
            int randomInt = Math.abs(random.nextInt() % input.size());
    
            // O(1)
            MusicTrack randomTrack = input.get(randomInt);
    
            // O(1)
            result.add(randomTrack);
    
            // O(n)
            input.remove(randomTrack);
        }
    
        return result;
    
    }
    
    
    public static void main(String[] args) {
    
        List<MusicTrack> musicTracks = MusicTrackFactory.generate(1000000);
    
        List<MusicTrack> result = shuffle3(musicTracks);
    
        result.stream().forEach(x -> System.out.println(x.getName()));
    }
    
    公共类MusicTrack程序{
    //O(n)就地交换
    公共静态列表shuffle3(列表输入){
    随机=新随机();
    int last=input.size()-1;
    而(最后>=0){
    int randomInt=Math.abs(random.nextInt()%input.size());
    //O(1)
    MusicTrack randomTrack=输入。获取(ra