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

62 阅读2分钟

问题描述

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

例如,给定歌单[5,3,2,1,4],真实的播放顺序是[5,2,4,1,3]。 保证歌曲中的id两两不同

测试样例

样例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]

问题理解

题目描述了一个特殊的随机播放规则:

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

数据结构选择

我们可以使用一个队列(Queue)来模拟这个过程:

  • 队列的特性是先进先出(FIFO),非常适合用来处理这种顺序播放和移动的操作。

算法步骤

  1. 初始化:将歌单中的所有歌曲放入队列。

  2. 播放歌曲

    • 从队列中取出第一首歌,并将其加入结果列表。
    • 如果队列中还有歌曲,则将当前队列的第一首歌移到队列的末尾。
  3. 重复:重复上述步骤,直到队列为空。

    from collections import deque
    
    def solution(n: int, a: list) -> list:
    # 使用deque初始化队列,deque的popleft和append操作时间复杂度为O(1)
    queue = deque(a)
    result = []
    
    while queue:
    # 播放当前队列中的第一首歌
    song = queue.popleft()
    result.append(song)
    
    # 如果队列中还有其他歌曲,将当前播放的歌曲移到队列末尾
    if queue:
        queue.append(queue.popleft())
    
    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])
    

时间复杂度:

  • 每次 popleft() 和 append() 都是 O(1) 操作,而队列中有 n 个元素,因此时间复杂度为 O(n)。

总结:

  • 通过使用 deque,代码的性能得到了提升,尤其在处理较大输入时。