问题描述
小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]
思路
看到这个题目的时候,在这个问题中,每首歌曲播放一次后,如果歌单中还有歌曲,当前第一首歌会被移到最后一首。这种操作类似于队列的出队(移除队首元素)和入队(将元素添加到队尾)操作,使得队列成为模拟这一过程的理想数据结构,所以直接使用队列以及队列的方法来解决问题。
AC代码
import java.util.Arrays;
import java.util.Queue;
import java.util.LinkedList;
public class Main {
public static int[] solution(int n, int[] a) {
// write code here
Queue<Integer> que=new LinkedList<>();
for(int i:a){
que.add(i);
}
int i=0;
int[] result=new int[n];
while(!que.isEmpty()){
result[i++]=que.poll();
if(!que.isEmpty()){
que.add(que.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}));
}
}
核心代码
while(!que.isEmpty()){
result[i++]=que.poll();
if(!que.isEmpty()){
que.add(que.poll());
}
}
- 将队头元素移到队尾。
总结
如果使用队列,这道题将非常容易就能够解出,但是如果开始没有想到队列这个方法,而是用数组的方法的话,那么可能需要手动管理数组的索引,这不仅增加了代码的复杂性,还可能导致数组越界等错误。所以在使用算法解答问题时,对方法的熟悉程度以及对正确方法的使用也十分重要。
学习心得
- 算法解题时使用的方法很重要。(这道题中使用队列可以大大简化代码逻辑。不需要手动管理数组或列表中的元素,队列提供了直接的方法来添加和移除元素。)
- 尽量利用常见的数据结构解题。(大多数程序员都对其有所了解,使用队列来解决问题可以使得解决方案更容易被其他开发者理解和接受。)