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

131 阅读3分钟

问题描述

小R有一个特殊的随机播放规则。他首先播放歌单中的第一首歌,播放后将其从歌单中移除。如果歌单中还有歌曲,则会将当前第一首歌移到最后一首。这个过程会一直重复,直到歌单中没有任何歌曲。

例如,给定歌单 [5, 3, 2, 1, 4],真实的播放顺序是 [5, 2, 4, 1, 3]

保证歌曲中的id两两不同。

思路分析

为了实现这个逻辑,我们可以使用一个队列(Queue)来模拟歌单的操作。队列的特点是先进先出(FIFO),非常适合这个场景。

  1. 初始化队列:将输入的歌单列表转换为一个队列。

  2. 模拟播放过程

    • 从队列中取出第一首歌(即队列的头部元素)。
    • 如果队列不为空,将当前队列的头部元素移到队列的尾部。
    • 重复上述步骤,直到队列为空。
  3. 记录播放顺序:在每次取出歌曲时,记录其播放顺序。

代码实现

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的卓越功能与优质教育资源,一方面夯实和拓展学科基础,另一方面勇于探索更高层次的知识领域,以实现个人学习能力的全方位提升。在这个过程中,我相信自己将不断突破自我,迈向更高的学习境界。