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

124 阅读4分钟

小R的随机播放问题

问题描述

在现代音乐应用中,随机播放一直是功能之一,具有创造性和娱乐性。小R的随机播放规则尤为有趣:她将首先播放歌单中的第一首歌,播放完成后,将此歌曲从歌单中移除。如果仍有未播放的歌曲,她会将当前第一首歌曲移到最后一位。这个过程会持续进行,直到歌单中的所有歌曲都被播放过。

例如,在给定的歌单 [5, 3, 2, 1, 4] 中,按照小R的播放规则,真实的播放顺序将会是 [5, 2, 4, 1, 3]。这种随机但有规则的方式让每首歌都能得到一次播放的机会,而不至于呆滞于列表的首位。

我们要为这个过程设计一个程序,能够接收歌曲列表并输出最后的播放顺序。

示例

为了更好地理解小R的播放规则,下面是一些典型的示例:

  • 示例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]

通过这样的示例,我们可以直观地看到,根据小R的规则,歌单中歌曲播放的顺序是如何变化的。

解题思路

为了解决小R的随机播放问题,我们可以利用队列(Queue)的数据结构。这是因为队列能够方便地实现先进先出的逻辑,正好符合小R的播放要求。

具体思路如下:

  1. 队列初始化:将输入的歌单转化为一个队列,以便我们能够高效地进行首尾操作。
  2. 执行播放:在每次循环中,我们将队列的首元素弹出,并将其添加到结果列表中。然后,如果队列中还有歌曲,我们会将下一个首元素再弹出一次,并将其附加到队列的尾部。
  3. 重复过程:这一过程会持续进行,直到队列为空。
  4. 输出播放顺序:最终,我们的结果列表便是所需的播放顺序。

这种思路是高度直观的,同时利用了队列的特性,使得实现过程简洁明了。

解题代码

以下是实现上述思路的 Python 代码:

from collections import deque

def solution(n: int, a: list) -> list:
    queue = deque(a)  # 初始化队列
    list1 = [0] * n  # 用于存储结果
    for i in range(n):
        list1[i] = queue.popleft()  # 播放当前第一首歌
        if len(queue) == 0:  # 如果队列为空,退出
            return list1
        queue.append(queue.popleft())  # 将下一首歌移到最后
    return list1

if __name__ == '__main__':
    print(solution(n = 5, a = [5, 3, 2, 1, 4]) == [5, 2, 4, 1, 3])
    print(solution(n = 4, a = [4, 1, 3, 2]) == [4, 3, 1, 2])
    print(solution(n = 6, a = [1, 2, 3, 4, 5, 6]) == [1, 3, 5, 2, 6, 4])

解题思路详细解析

在代码实现中,我们首先使用了 collections.deque 进行队列的初始化,其优势在于该数据结构能够高效地执行弹出和添加操作。对于这道题来说,能够以 O(1) 的时间复杂度在队首和队尾进行操作,使得我们的方案更加高效。

  • 队列操作:使用 queue.popleft() 来获取并移除队列的首元素,这个元素对应于当前播放的歌曲。
  • 播放与重排:我们把播放的歌曲保存在 list1 列表中。如果队列不为空,接着继续执行弹出操作,并将下一个元素放入队列的尾部,这样就能确保我们的同步过程。
  • 循环直至空:每次操作后,我们检查队列的长度,直到所有歌曲都被播放完。

这种方法较为直观,并且逻辑清晰,全程保持了 O(n) 的时间复杂度,适合处理大量的歌曲数据。

复杂度分析

在分析时间和空间复杂度时,可以得出如下结论:

  1. 时间复杂度:由于主要操作包括 popleft()append(),每次都在 O(1) 的时间内完成。总体上,我们对每首歌都进行了处理,因此时间复杂度为 O(n),其中 n 是歌单中的歌曲数量。

  2. 空间复杂度:我们使用了一个额外的列表 list1 来存储结果,故空间复杂度为 O(n)。此外,队列的存储也是 O(n)。因此,空间复杂度总体上也是 O(n)。

通过对这个问题的解答,我们不仅掌握了如何使用队列实现小R的随机播放逻辑,还进一步理解了数据结构在算法设计中的重要性。在实际开发中,使用恰当的数据结构能够大幅提高代码的执行效率与可读性。未来我会继续关注如何选择合适的数据结构来应对不同的算法问题,积累更多实践经验。