小R的随机播放顺序|豆包MarsCode AI刷题

99 阅读3分钟

小R的随机播放顺序

问题描述

小R有一个特殊的随机播放规则。他首先播放歌单中的第一首歌,播放后将其从歌单中移除。如果歌单中还有歌曲,则会将当前第一首歌移到最后一首。这个过程会一直重复,直到歌单中没有任何歌曲。

例如,给定歌单 [5, 3, 2, 1, 4],真实的播放顺序是 [5, 2, 4, 1, 3]

保证歌曲中的id两两不同。


测试样例

样例1:

输入:n = 5 ,a = [5, 3, 2, 1, 4]
输出:[5, 2, 4, 1, 3]

样例2:

输入:n = 4 ,a = [4, 1, 3, 2]
输出:[4, 3, 1, 2]

样例3:

输入:n = 6 ,a = [1, 2, 3, 4, 5, 6]
输出:[1, 3, 5, 2, 6, 4]

分析问题

这个问题描述了一个特殊的随机播放规则,其中歌单的处理遵循以下步骤:

播放当前歌单的第一首歌,并将其从歌单中移除。

如果歌单中仍有歌曲,则将新的第一首歌移到歌单的末尾。

重复上述步骤,直到歌单为空。

我们可以观察到,这种播放规则并不完全是随机的,而是遵循一种特定的顺序。为了生成正确的播放顺序,我们可以使用一个队列(或列表)来模拟这个过程。

代码

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

public class Main {
    public static int[] solution(int n, int[] a) {
        // 使用LinkedList来模拟播放列表
        List<Integer> playlist = new LinkedList<>();
        for (int song : a) {
            playlist.add(song);
        }
        
        List<Integer> result = new LinkedList<>();
        
        while (!playlist.isEmpty()) {
            // 播放第一首歌并将其从列表中移除
            int currentSong = playlist.remove(0);
            result.add(currentSong);
            
            // 如果播放列表中还有歌曲,将当前的第一首歌(原来的第二首)移到列表末尾
            if (!playlist.isEmpty()) {
                int moveToEnd = playlist.remove(0);
                playlist.add(moveToEnd);
            }
        }
        
        // 将结果列表转换回数组
        int[] answer = new int[result.size()];
        for (int i = 0; i < result.size(); i++) {
            answer[i] = result.get(i);
        }
        
        return answer;
    }

    public static void main(String[] args) {
        // 测试用例
        System.out.println(Arrays.equals(solution(5, new int[]{5, 3, 2, 1, 4}), new int[]{5, 2, 4, 1, 3}));
        System.out.println(Arrays.equals(solution(4, new int[]{4, 1, 3, 2}), new int[]{4, 3, 1, 2}));
        System.out.println(Arrays.equals(solution(6, new int[]{1, 2, 3, 4, 5, 6}), new int[]{1, 3, 5, 2, 6, 4}));
    }
}

代码解析

solution 方法

  1. 初始化播放列表

    • 使用 LinkedList<Integer> 来模拟播放列表,因为 LinkedList 提供了高效的 remove(0) 和 add(E e) 操作,分别用于移除和添加元素到列表的开头和末尾。
    • 遍历输入数组 a,将每首歌曲添加到 playlist 中。
  2. 播放过程

    • 使用一个 while 循环,直到 playlist 为空。
    • 在每次循环中,移除并播放 playlist 的第一首歌(remove(0)),将其添加到结果列表 result 中。
    • 如果 playlist 不为空,移除当前的第一首歌(原来的第二首,因为第一首已经被移除),并将其添加到 playlist 的末尾。这里有一个小错误:代码实际上移除了当前的第一首歌(即原来的第一首被移除后的新第一首),但按照问题描述,应该是将新的第一首歌(即原来的第二首)移到末尾。不过,由于每次循环都会移除当前的第一首歌,所以这里的操作在结果上是正确的,只是解释上稍有偏差。正确的理解应该是:在移除第一首歌后,当前的第一首歌(在移除操作前是第二首)变成了新的处理目标。
  3. 返回结果:

    • 创建一个整数数组 answer,大小与结果列表 result 相同。
    • 遍历 result,将其元素复制到 answer 数组中。
    • 返回 answer 数组。