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

62 阅读3分钟

问题分析

题目要求我们模拟一个特殊的播放规则,具体的操作是:

  1. 首先播放歌单中的第一首歌,播放后将其从歌单中移除。
  2. 如果歌单中还有歌曲,则将当前的第一首歌移到歌单的最后一首。
  3. 重复上述过程,直到歌单为空。

示例分析

假设给定的歌单是 [5, 3, 2, 1, 4],我们逐步分析这个过程:

  1. 初始歌单: [5, 3, 2, 1, 4]

    • 播放第一首歌 5,然后移除它。新的歌单变为 [3, 2, 1, 4]
    • 将当前的第一首歌 3 移到歌单的最后。新的歌单变为 [2, 1, 4, 3]
  2. 当前歌单: [2, 1, 4, 3]

    • 播放第一首歌 2,然后移除它。新的歌单变为 [1, 4, 3]
    • 将当前的第一首歌 1 移到歌单的最后。新的歌单变为 [4, 3, 1]
  3. 当前歌单: [4, 3, 1]

    • 播放第一首歌 4,然后移除它。新的歌单变为 [3, 1]
    • 将当前的第一首歌 3 移到歌单的最后。新的歌单变为 [1, 3]
  4. 当前歌单: [1, 3]

    • 播放第一首歌 1,然后移除它。新的歌单变为 [3]
    • 将当前的第一首歌 3 移到歌单的最后,结果还是 [3]
  5. 当前歌单: [3]

    • 播放第一首歌 3,然后移除它。新的歌单变为空 []

最终播放顺序是 [5, 2, 4, 1, 3]

解题思路

这个问题的核心是模拟给定的播放规则,并且需要确保每次操作都正确地反映在歌单的顺序变化中。可以利用 队列(FIFO结构)来模拟这个过程。

  1. 队列的特点:队列具有先进先出的特性,非常适合模拟这种“移除首部、添加尾部”的操作。

  2. 过程

    • 我们从歌单的队首开始,播放并移除歌曲。
    • 如果队列中还有歌曲,则将当前队首的歌曲移到队尾。
    • 继续执行这个过程直到队列为空。

解题步骤

  1. 将歌单转化为队列。

  2. 循环执行以下操作直到队列为空:

    • 播放队列中的第一首歌,并将其移除。
    • 将剩下的第一首歌移到队尾(如果队列不为空)。
  3. 输出最终播放的顺序。

代码实现

pythonCopy Code
from collections import deque

def play_song_list(playlist):
    # 将歌单转换为队列
    queue = deque(playlist)
    result = []
    
    while queue:
        # 播放并移除当前队首歌曲
        result.append(queue.popleft())
        
        # 如果队列中还有歌曲,将当前队首移到队尾
        if queue:
            queue.append(queue.popleft())
    
    return result

# 示例
playlist = [5, 3, 2, 1, 4]
result = play_song_list(playlist)
print(result)  # 输出: [5, 2, 4, 1, 3]

代码解释

  1. 队列初始化:我们使用 Python 内置的 deque 来表示队列,这样可以高效地进行队首和队尾的操作。

  2. while queue: :当队列非空时,继续播放并操作队列。

    • queue.popleft() 用来播放并移除队首的歌曲。
    • 如果队列中仍然有歌曲,执行 queue.append(queue.popleft()) 将队首歌曲移动到队尾。
  3. 结果返回:最终返回的是一个列表 result,包含了播放的顺序。

时间复杂度分析

  • 入队和出队操作的时间复杂度是 O(1),因为队列提供了高效的队首和队尾操作。
  • 我们需要处理 n 歌曲,执行 n 次操作,每次操作都涉及到常数时间的队列操作,所以时间复杂度为 O(n)。

空间复杂度分析

  • 我们需要使用一个队列来存储歌单,因此空间复杂度是 O(n),其中 n 是歌单的长度。

总结

通过使用队列模拟这个特殊的播放规则,我们能够有效地模拟出播放顺序并且输出结果。时间复杂度为 O(n),适合处理较大的数据规模。