“小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]
三、题目解析
3.1代码思路
- 初始化队列:使用
LinkedList实现Queue接口,并将所有歌曲ID放入队列中。 - 模拟播放过程:使用
poll()方法从队列中取出并播放当前第一首歌。如果队列中还有歌曲,使用poll()方法取出当前第一首歌,并使用add()方法将其移到队列末尾。 - 记录播放顺序:将每次播放的歌曲ID记录到
result数组中。
13. 定义 applyOperation 方法
import java.util.LinkedList;
import java.util.Queue;
public class Main {
public static int[] solution(int n, int[] a) {
// 创建一个队列,并将所有歌曲ID放入队列中
Queue<Integer> queue = new LinkedList<>();
for (int song : a) {
queue.add(song);
}
// 创建一个数组来存储播放顺序
int[] result = new int[n];
int index = 0;
// 模拟播放过程
while (!queue.isEmpty()) {
// 取出并播放当前第一首歌
int currentSong = queue.poll();
result[index++] = currentSong;
// 如果队列中还有歌曲,将当前第一首歌移到队列末尾
if (!queue.isEmpty()) {
int nextSong = queue.poll();
queue.add(nextSong);
}
}
return result;
}
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}));
}
}
四、知识总结
这段代码通过结合队列操作与循环模拟的方式,较好地实现了自定义的播放机制,并利用队列数据结构的特点简化了复杂的逻辑。使用 Queue 数据结构来模拟播放列表,按照 FIFO 规则取出当前歌曲,实现顺序播放。利用队列的特性来处理“当前歌曲播放后,下一个歌曲移到末尾”的需求,这种操作非常适合队列。 使用 while 循环,通过 poll() 方法不断从队列中取出元素,直到队列为空。循环中的每一步都模拟了一个播放过程。这种模拟方式便于对流程进行控制,使得代码能按需改变播放顺序,例如将“跳过”的歌曲重新添加到队列末尾。用一个 result 数组来保存每首歌曲的播放顺序,确保了最终输出格式符合要求。每轮循环都通过 poll() 移除队首元素并条件性地重新插入元素,实现队列中元素的状态更新。这种状态更新思想适合处理类似调度、轮换等需求。