题目解析:解决“小R的随机播放顺序”问题
思路分析:
- 首先播放歌单中的第一首歌,播放后将其从歌单中移除。
- 如果歌单中还有歌曲,则会将当前第一首歌移到最后一首。
- 这个过程会一直重复,直到歌单中没有任何歌曲。
解题步骤:
-
初始化队列:
- 将所有歌曲加入队列。
-
模拟播放过程:
-
循环直到队列为空:
- 播放当前队列的第一首歌(即
poll操作)。 - 如果队列中还有歌曲,将当前第一首歌移到队列的末尾(即
poll后再add)。
- 播放当前队列的第一首歌(即
-
-
存储结果:
- 将每次播放的歌曲按顺序存储在结果数组中。
图解:
-
使用队列(Queue):
-
将所有歌曲加入队列。
- 循环直到队列为空:
-
播放当前队列的第一首歌(即
poll操作)。 -
如果队列中还有歌曲,将当前第一首歌移到队列的末尾(即
poll后再add)。
-
-
使用数组模拟队列:
-
使用
front和rear两个指针来模拟队列的头部和尾部。- 循环直到
front超过rear:
- 循环直到
-
播放当前队列的第一首歌(即
a[front++])。 -
如果还有歌曲,将当前第一首歌移到数组的末尾(即
a[++rear] = a[front++])。
-
代码详解(使用队列):
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
public class Main {
public static int[] solution(int n, int[] a) {
// 使用队列来模拟播放顺序
Queue<Integer> queue = new LinkedList<>();
for (int song : a) {
queue.add(song);
}
int[] result = new int[n];
int index = 0;
while (!queue.isEmpty()) {
// 播放第一首歌
result[index++] = queue.poll();
// 如果还有歌曲,将当前第一首歌移到最后一首
if (!queue.isEmpty()) {
queue.add(queue.poll());
}
}
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来模拟播放顺序,因为队列的先进先出特性非常适合模拟播放和移动歌曲的操作。
时间复杂度分析
- 初始化队列/数组和模拟播放过程的时间复杂度均为 O(n)。
- 总时间复杂度为 O(n)。
问题分解与抽象
理解播放规则:
- 首先播放歌单中的第一首歌,播放后将其从歌单中移除。
- 如果歌单中还有歌曲,则会将当前第一首歌移到最后一首。
- 这个过程会一直重复,直到歌单中没有任何歌曲。
通过使用队列数据结构,我们可以高效地模拟题目描述的播放规则,并得到正确的播放顺序。这个方法简单直观,且时间复杂度为线性,非常适合处理这个问题。