小R的随机播放顺序
这道题目描述了一个特殊的歌曲播放顺序:小R在播放歌曲的过程中会遵循“播放第一首歌并移除”以及“将当前第一首歌移到末尾”的规则。我们需要基于该规则输出最终的真实播放顺序。
解题思路
从题目描述来看,核心步骤可以归纳为:
- 播放和移除:播放当前第一首歌,然后将其从歌单中移除。
- 移到末尾:如果歌单中还有剩余歌曲,将当前第一首歌移到歌单的末尾。
- 循环执行:重复上述步骤直到歌单为空。
这个过程实际上就是一个循环队列操作:将第一首歌播放并移除,然后将新的第一首歌移至队尾。这种操作可以使用队列的数据结构来实现。
具体实现步骤
- 使用一个列表(模拟队列)存储歌曲。
- 设立一个结果列表
result,用于保存每次播放的歌曲。 - 持续执行以下循环,直到歌单为空:
- 将当前第一首歌从队列中移除,并将其添加到结果列表中。
- 若队列中还有歌曲,将当前第一首歌移到末尾。
代码实现
根据上面的思路,我们可以编写以下代码:
def solution(n: int, a: list) -> list:
# 初始化播放结果列表
result = []
# 当歌单非空时,执行循环操作
while a:
# 1. 播放并移除第一首歌
result.append(a.pop(0))
# 2. 如果还有歌,将新的第一首歌移到末尾
if a:
a.append(a.pop(0))
return result
# 测试用例
if __name__ == '__main__':
print(solution(n = 5, a = [5, 3, 2, 1, 4]) == [5, 2, 4, 1, 3]) # 应输出 True
print(solution(n = 4, a = [4, 1, 3, 2]) == [4, 3, 1, 2]) # 应输出 True
print(solution(n = 6, a = [1, 2, 3, 4, 5, 6]) == [1, 3, 5, 2, 6, 4]) # 应输出 True
代码详解
- 播放并移除:使用
a.pop(0)将当前歌单的第一首歌移除并添加到result中,记录播放顺序。 - 移到末尾:当
a中还有剩余歌曲时,再执行a.append(a.pop(0)),将新的第一首歌移到队尾。 - 循环终止:当歌单
a为空时,即所有歌曲都播放完毕,退出循环并返回播放结果result。
样例分析
-
样例1:
- 输入:
[5, 3, 2, 1, 4] - 执行过程:
- 播放 5,剩余
[3, 2, 1, 4]→result = [5] - 将 3 移到末尾,变成
[2, 1, 4, 3] - 播放 2,剩余
[1, 4, 3]→result = [5, 2] - 将 1 移到末尾,变成
[4, 3, 1] - 播放 4,剩余
[3, 1]→result = [5, 2, 4] - 将 3 移到末尾,变成
[1, 3] - 播放 1,剩余
[3]→result = [5, 2, 4, 1] - 播放 3,剩余
[]→result = [5, 2, 4, 1, 3]
- 播放 5,剩余
- 输出:
[5, 2, 4, 1, 3],符合预期。
- 输入:
-
样例2:
- 输入:
[4, 1, 3, 2] - 输出过程类似,最终得到
[4, 3, 1, 2],符合预期。
- 输入:
-
样例3:
- 输入:
[1, 2, 3, 4, 5, 6] - 按照相同逻辑,最终结果为
[1, 3, 5, 2, 6, 4]。
- 输入:
总结与思考
这个算法利用了队列的**先进先出(FIFO)**性质,同时每次循环都将第一首歌移除并在特定条件下将新的第一首歌移到末尾。这种操作类似于队列的旋转,利用 pop 和 append 可以轻松实现。
在实际应用中,这种策略适用于循环任务分配、动态排序等场景,通过简单的队列操作即可完成复杂的顺序安排。