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

44 阅读3分钟

一、问题描述 小R有一个独特的随机播放模式。初始时,播放歌单中的第一首歌并将其从歌单移除,如果歌单还有歌曲,就把当前的第一首歌移到歌单末尾,如此循环,直至歌单为空。例如,给定歌单 [5, 3, 2, 1, 4],实际的播放顺序是 [5, 2, 4, 1, 3]。 二、代码实现 以下是用Python解决此问题的代码: from collections import deque

def solution(n, a): playlist = deque(a) result = [] while playlist: result.append(playlist.popleft()) if playlist: playlist.append(playlist.popleft()) return result

三、代码逻辑解析 (一)数据结构选择 1.使用双端队列(deque) 1.在Python中,双端队列是一个非常适合这个问题的数据结构。它允许我们在队列的两端(头部和尾部)高效地进行插入和删除操作。在这里,我们使用双端队列来表示歌单,因为我们需要从头部移除歌曲(模拟播放),并且有时还需要把头部的歌曲移到尾部。 (二)循环播放过程 1.初始化播放列表和结果列表 1.playlist = deque(a):将输入的歌单 a 转换为双端队列 playlist,这样就可以方便地进行后续操作。 2.result = []:创建一个空列表 result,用于存储最终的播放顺序。 2.模拟播放循环 1.while playlist::只要歌单不为空,就持续循环。 2.result.append(playlist.popleft()):首先,播放歌单中的第一首歌(从双端队列的头部移除元素),并将其添加到结果列表 result 中。这一步模拟了实际的播放操作。 3.if playlist::检查歌单是否还有剩余歌曲。 4.playlist.append(playlist.popleft()):如果歌单还有歌曲,就将新的第一首歌(再次从双端队列头部移除元素)移到歌单的末尾(通过双端队列的 append 操作)。这个操作符合问题中的随机播放规则。 (三)返回结果 1.return result:当歌单为空时,循环结束,返回存储播放顺序的结果列表 result。 四、时间复杂度和空间复杂度分析 (一)时间复杂度 1.由于代码中只对歌单中的每个元素进行了常数次操作(一次或两次的移除和可能的添加操作),并且循环次数等于歌单的长度 n,所以时间复杂度为 O(n),其中 n 是歌单的长度。 (二)空间复杂度 1.代码创建了一个双端队列 playlist 和一个结果列表 result。双端队列最多存储 n 个元素,结果列表也最多存储 n 个元素,所以总的空间复杂度为 O(n),其中 n 是歌单的长度。 五、优化建议 (一)空间优化 1.可以考虑在不使用额外结果列表的情况下直接构建播放顺序。例如,可以通过计算每个元素在最终播放顺序中的位置索引,直接输出播放顺序,从而降低空间复杂度。 (二)边界条件优化 1.目前代码对空歌单的情况没有特殊处理。可以添加对输入歌单为空的情况的判断,返回一个空的播放顺序列表或者进行适当的提示。