问题描述
小R有一个特殊的随机播放规则。他首先播放歌单中的第一首歌,播放后将其从歌单中移除。如果歌单中还有歌曲,则会将当前第一首歌移到最后一首。这个过程会一直重复,直到歌单中没有任何歌曲。
例如,给定歌单 [5, 3, 2, 1, 4],真实的播放顺序是 [5, 2, 4, 1, 3]。
保证歌曲中的id两两不同。
思路分析
为了实现这个逻辑,我们可以使用一个队列(Queue)来模拟歌单的操作。队列的特点是先进先出(FIFO),非常适合这个场景。
-
初始化队列:将输入的歌单列表转换为一个队列。
-
模拟播放过程:
- 从队列中取出第一首歌(即队列的头部元素)。
- 如果队列不为空,将当前队列的头部元素移到队列的尾部。
- 重复上述步骤,直到队列为空。
-
记录播放顺序:在每次取出歌曲时,记录其播放顺序。
代码实现
python代码
from collections import deque
def solution(n: int, a: list) -> list:
# 初始化队列
queue = deque(a)
result = []
# 模拟播放过程
while queue:
# 取出第一首歌
first_song = queue.popleft()
result.append(first_song)
# 如果队列不为空,将当前第一首歌移到最后一首
if queue:
next_song = queue.popleft()
queue.append(next_song)
return result
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])
关键步骤解释
deque(a):将输入的歌单列表转换为一个双端队列。queue.popleft():从队列的头部取出元素。queue.append(next_song):将元素添加到队列的尾部。
为什么使用队列
1. 先进先出(FIFO)特性
队列的特性是先进先出(FIFO),这意味着最先进入队列的元素会最先被取出。这与题目中描述的播放规则非常吻合:
- 每次播放歌单中的第一首歌,并将其从歌单中移除。
- 如果歌单中还有歌曲,则将当前第一首歌移到最后一首。
2. 模拟播放过程
队列可以很好地模拟这个播放过程:
popleft()操作可以取出队列的头部元素,即当前的第一首歌。append()操作可以将元素添加到队列的尾部,即将当前的第一首歌移到最后一首。
3. 高效的操作
队列提供了高效的 popleft() 和 append() 操作,时间复杂度均为 O(1)。这意味着我们可以快速地进行歌曲的取出和移动操作,而不需要遍历整个列表。
4. 代码简洁性
使用队列可以使代码更加简洁和直观。通过队列的操作,我们可以清晰地表达题目中的播放规则,而不需要复杂的索引操作或列表切片。
总结
通过运用智能刷题工具——豆包MarsCode AI,我在知识掌握、思维训练和问题解决能力方面取得了长足的进步。展望未来,我将继续融合AI的卓越功能与优质教育资源,一方面夯实和拓展学科基础,另一方面勇于探索更高层次的知识领域,以实现个人学习能力的全方位提升。在这个过程中,我相信自己将不断突破自我,迈向更高的学习境界。