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

100 阅读3分钟

问题描述

小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. 调整剩余歌单:若歌单中还有歌曲,将当前的第一首歌移动到歌单的最后。
  3. 重复操作:继续执行上述两步,直到歌单为空。

关键问题分析

1. 如何高效地调整歌单顺序?

直接用列表操作(如 pop(0))移除第一首歌需要移动后续所有元素,效率较低。可以使用队列结构来实现高效的队首移除和队尾添加。

2. 如何判断播放结束?

当歌单为空时,停止操作。

代码实现

使用列表的解法

def solution(n, a):
    result = []
    while a:
        # 播放当前第一首歌
        result.append(a.pop(0))
        # 若还有歌曲,调整顺序
        if a:
            a.append(a.pop(0))
    return result

使用队列的优化解法

from collections import deque

def solution(n, a):
    playlist = deque(a)  # 使用双端队列初始化歌单
    result = []
    while playlist:
        # 播放当前第一首歌
        result.append(playlist.popleft())
        # 若还有歌曲,调整顺序
        if playlist:
            playlist.append(playlist.popleft())
    return result

知识点总结

1. 队列的应用

collections.deque 是 Python 中的双端队列,支持高效的队首移除(popleft)和队尾添加(append),非常适合实现类似“循环队列”的操作。

2. 时间复杂度分析

  • 列表实现:移除第一首歌(pop(0))的时间复杂度为 O(n)O(n),总复杂度为 O(n2)O(n^2)
  • 队列实现popleftappend 均为 O(1)O(1),总复杂度为 O(n)O(n)

3. 边界条件处理

  • 若歌单为空,无需任何操作,直接返回空列表。
  • 输入数据保证合法性,无需额外验证。

4. 提前终止优化

由于操作始终处理队列的首尾,不存在提前终止的可能性,完整遍历歌单是必需的。

思考与优化

1. 其他数据结构的实现

若歌单非常大,可以考虑用链表来实现类似操作,节省内存。

2. 更复杂的规则

可以扩展到更复杂的随机播放规则,例如每次移动两首歌到队尾,或者按照一定优先级调整播放顺序等。