小R的随机播放顺序问题| 豆包MarsCode AI刷题

96 阅读2分钟

题目解析:解决“小R的随机播放顺序”问题

思路分析

  1. 首先播放歌单中的第一首歌,播放后将其从歌单中移除。
  2. 如果歌单中还有歌曲,则会将当前第一首歌移到最后一首。
  3. 这个过程会一直重复,直到歌单中没有任何歌曲。

解题步骤

  1. 初始化队列

    • 将所有歌曲加入队列。
  2. 模拟播放过程

    • 循环直到队列为空:

      • 播放当前队列的第一首歌(即 poll 操作)。
      • 如果队列中还有歌曲,将当前第一首歌移到队列的末尾(即 poll 后再 add)。
  3. 存储结果

    • 将每次播放的歌曲按顺序存储在结果数组中。

图解

  • 使用队列(Queue)

    1. 将所有歌曲加入队列。

      • 循环直到队列为空:
    2. 播放当前队列的第一首歌(即 poll 操作)。

    3. 如果队列中还有歌曲,将当前第一首歌移到队列的末尾(即 poll 后再 add)。

  • 使用数组模拟队列

    1. 使用 front 和 rear 两个指针来模拟队列的头部和尾部。

      • 循环直到 front 超过 rear
    2. 播放当前队列的第一首歌(即 a[front++])。

    3. 如果还有歌曲,将当前第一首歌移到数组的末尾(即 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)。

问题分解与抽象

理解播放规则

  • 首先播放歌单中的第一首歌,播放后将其从歌单中移除。
  • 如果歌单中还有歌曲,则会将当前第一首歌移到最后一首。
  • 这个过程会一直重复,直到歌单中没有任何歌曲。

通过使用队列数据结构,我们可以高效地模拟题目描述的播放规则,并得到正确的播放顺序。这个方法简单直观,且时间复杂度为线性,非常适合处理这个问题。