1. 代码整体结构与功能概述
这段 Java 代码主要实现了按照一种特殊规则来生成歌曲播放顺序的功能。整体结构上,代码包含一个名为 Main 的类,类中定义了一个静态方法 solution 用于解决核心的歌曲播放顺序计算问题,以及一个 main 方法用于对 solution 方法进行简单的测试验证。
solution 方法接收两个参数,一个是表示歌曲总数的整数 n,另一个是包含歌曲 id 的整数数组 a,通过模拟给定的特殊播放规则,最终返回按照该规则生成的实际播放顺序的整数数组。而 main 方法则通过调用 solution 方法,并使用 Arrays.equals 方法来对比实际结果与预期结果是否一致,以此验证 solution 方法的正确性。
2. solution 方法详细解析
2.1 引入必要的数据结构 - 队列(使用 LinkedList 模拟)
LinkedList<Integer> queue = new LinkedList<>();
在 solution 方法中,首先创建了一个 LinkedList 类型的对象 queue,这里利用了 LinkedList 实现了 Deque 接口的特性,使其可以方便地作为队列来使用。队列这种数据结构非常契合本题中对歌单操作的模拟需求,因为它遵循先进先出(FIFO)的原则,正好对应歌单中歌曲的顺序以及按规则操作时的先后顺序逻辑。
2.2 将歌曲列表元素添加到队列中
for (int num : a) {
queue.add(num);
}
通过一个增强 for 循环,遍历输入的歌曲 id 数组 a,并将每个元素依次添加到刚刚创建的队列 queue 中。这样就把初始的歌单信息以队列的形式进行了存储,此时队列头部元素就代表歌单中的第一首歌,队列尾部元素则代表最后一首歌,为后续按照规则操作奠定了基础。
2.3 初始化结果数组并设置索引
int[] result = new int[n];
int index = 0;
接下来,创建了一个长度为 n(歌曲总数)的整数数组 result,这个数组将用于存储最终按照规则生成的播放顺序。同时,定义了一个变量 index,初始化为 0,它的作用是在后续往 result 数组中添加元素时,标记当前应该放置元素的位置,随着播放顺序的逐步生成,index 会不断递增,确保元素能按顺序存入 result 数组中。
2.4 核心循环 - 模拟播放与移动歌曲的过程
while (!queue.isEmpty()) {
// 播放当前第一首歌(取出队列头部元素添加到结果列表)
result[index++] = queue.poll();
if (!queue.isEmpty()) {
// 将当前第一首歌移到最后一首(取出头部元素再添加到队列尾部)
queue.add(queue.poll());
}
}
这是整个 solution 方法的核心逻辑所在,通过一个 while 循环来不断模拟歌曲的播放和移动操作,直到队列为空,表示所有歌曲都已经按照规则播放完毕。
-
播放操作:
在每次循环中,首先执行result[index++] = queue.poll();这行代码,调用queue.poll()方法会取出队列头部的元素,也就是当前歌单中的第一首歌,然后将其赋值给result数组中当前由index所指向的位置,并接着将index的值加1,以便下一次存储元素时放置在正确的下一个位置。这一步完美地模拟了按照规则播放第一首歌并将其从歌单(队列)中移除的过程。 -
移动操作:
接着,通过if (!queue.isEmpty()) {... }这个条件判断语句来检查队列是否还有剩余歌曲。如果队列不为空,意味着还有歌曲需要按照规则继续操作,此时执行queue.add(queue.poll());代码,先调用queue.poll()取出当前队列头部元素(此时这个元素已经变成了原来的第二首歌,因为上一步播放操作移除了第一首歌),然后再调用queue.add(...)将取出的这个元素添加到队列的尾部,从而实现了将当前的第一首歌移到最后一首的规则要求。
整个循环不断重复上述播放和移动操作,直到队列为空,此时 result 数组中就完整地存储了按照特殊规则生成的歌曲播放顺序。
2.5 返回结果
最后,solution 方法返回 result 数组,这个数组就是按照给定规则生成的实际播放顺序数组,完成了整个歌曲播放顺序计算的功能。