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

51 阅读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]

解题思路

这个问题可以通过模拟整个播放和移动的过程来解决。根据题目描述,每次我们取出当前列表的第一个元素作为播放的歌曲,然后将这首歌曲从列表中移除。如果列表中还有歌曲,则将当前的第一首歌移到最后一首。这个过程一直重复,直到列表为空。

图解步骤

以样例 [5, 3, 2, 1, 4] 为例,操作步骤如下:

  1. 播放 5,列表变为 [3, 2, 1, 4]
  2. 将 3 移到末尾,列表变为 [2, 1, 4, 3]
  3. 播放 2,列表变为 [1, 4, 3]
  4. 将 1 移到末尾,列表变为 [4, 3, 1]
  5. 播放 4,列表变为 [3, 1]
  6. 将 3 移到末尾,列表变为 [1, 3]
  7. 播放 1,列表变为 [3]
  8. 播放 3,列表为空。

代码实现

下面是 Python 代码实现:


def solution(n: int, a: list) -> list:
    result = []
    while a:
        # 播放第一首歌
        result.append(a.pop(0))
        # 如果还有歌曲,则将当前第一首移到最后
        if a:
            a.append(a.pop(0))
    return result

时间和空间复杂度分析

时间复杂度: 每次处理一个元素需要进行两次列表操作(pop(0)append),每个 pop(0) 操作的时间复杂度为 O(n),因为它需要移动列表中的所有其他元素。因此,总的时间复杂度为 O(n^2),其中 n 是列表的长度。

空间复杂度: 这个算法使用了额外的列表 result 来存储播放顺序,因此空间复杂度为 O(n),其中 n 是输入列表的长度。

优化思考

这个解法中,pop(0) 是一个较为耗时的操作,因为每次调用都会导致数组中剩余元素的移动。如果能使用一个更高效的数据结构来避免这种开销,比如双端队列(collections.deque),那么性能会有所提升。使用 deque 可以将 pop(0)append 操作的复杂度降至 O(1),从而使得总体时间复杂度降为 O(n)。