(Java解题)队列:小R的随机播放顺序 | 豆包MarsCode AI刷题

111 阅读2分钟

题目:小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]


解题思路

  1. 理解问题

    • 我们需要模拟一个播放顺序,每次播放第一首歌,然后将其移除。
    • 如果还有歌曲,将当前第一首歌移到最后一首。
    • 重复上述过程,直到所有歌曲都被播放。
  2. 数据结构选择

    • 使用队列(Queue)来模拟播放顺序。队列的特性是先进先出(FIFO),非常适合模拟播放和移动操作。
  3. 算法步骤

    • 将所有歌曲加入队列。
    • 循环直到队列为空:
      • 播放当前队列的第一首歌(即出队)。
      • 如果队列不为空,将当前第一首歌移到队列末尾(即再次出队并入队)。
  4. 代码实现

import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;

public class Main {
    public static int[] solution(int n, int[] a) {
        // write code here
        Queue<Integer> q = new LinkedList<>();
        int index = 0;
        for (int song : a) {
            q.offer(song);
        }
        while(!q.isEmpty()){
            // 播放当前第一首歌
            a[index++] = q.poll();
            
            // 如果队列不为空,将当前第一首歌移到队列末尾
            if (!q.isEmpty()) {
                q.offer(q.poll());
            }
        }
        
        return a;
    }

    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}));
    }
}

时间复杂度:O(n)

空间复杂度:O(n)

关键点总结

  • 队列的使用:利用队列的先进先出特性,模拟歌曲的播放和移动操作。
  • 循环控制:通过while循环控制播放过程,直到队列为空。
  • 边界条件:确保在队列不为空时才进行歌曲的移动操作。

心得

  • 直接把数组放到队列里实现起来比较简单。
  • 循环里面一开始我的思路是两个元素一组,一个出队,一个放到队尾,但是还要处理奇数个和偶数个元素两种情况。问了AI,看到AI给出的代码发现自己想复杂了,直接在while循环里操作就好。
  • AI给出的代码中,先出队再入队直接用一句q.offer(q.poll())完事,代码十分简洁巧妙,学到了~