小R的随机播放顺序 | 豆包MarsCode AI刷题
简单的使用一下队列的先进先出概念即可
摘要
本文介绍了一个关于特殊随机播放规则的算法。给定一个歌单,以特定的方式进行播放:先播放第一首歌,之后将第二首歌移到歌单的末尾,重复该过程直到歌单为空。本文详细说明了算法思路,并提供了Python和Go的代码实现。
问题描述
小R有一个包含歌曲的随机播放规则。他首先播放歌单中的第一首歌,播放后将歌单的第二首歌移动到歌单末尾。如果歌单中还有歌曲,则继续从当前第一首歌开始重复这个过程,直到歌单中没有歌曲。
例如,给定歌单 [5, 3, 2, 1, 4]
,真实的播放顺序是 [5, 2, 4, 1, 3]
。
保证歌单中的歌曲ID两两不同。
示例
-
输入:
n = 5, a = [5, 3, 2, 1, 4]
输出:[5, 2, 4, 1, 3]
-
输入:
n = 4, a = [4, 1, 3, 2]
输出:[4, 3, 1, 2]
-
输入:
n = 6, a = [1, 2, 3, 4, 5, 6]
输出:[1, 3, 5, 2, 6, 4]
原理分析
1. 初始化队列
我们可以用一个空列表 queue
来保存播放顺序。
2. 循环处理
在主循环中,执行以下步骤:
- 将
a
的第一个元素(即当前的第一首歌)添加到queue
。 - 删除
a
的第一个元素。 - 检查
a
是否有至少两个元素。如果有,则将新的第一首歌移动到a
的末尾。
3. 结束条件
当 a
为空时,循环结束,queue
即为最终的播放顺序。
代码实现
Python代码
from typing import List
def solution(n: int, a: List[int]) -> List[int]:
"""
接收一个整数 n 和一个列表 a,通过特定的队列处理规则返回一个新的排列。
"""
queue = [] # 初始化结果队列
while a:
# 将第一个元素添加到队列
queue.append(a.pop(0))
# 如果 a 中还剩下至少一个元素,则将下一个元素放到 a 的末尾
if len(a) > 1:
a.append(a.pop(0))
return queue
if __name__ == "__main__":
# 测试用例
print(solution(5, [5, 3, 2, 1, 4]) == [5, 2, 4, 1, 3]) # 应输出 True
print(solution(4, [4, 1, 3, 2]) == [4, 3, 1, 2]) # 应输出 True
print(solution(6, [1, 2, 3, 4, 5, 6]) == [1, 3, 5, 2, 6, 4]) # 应输出 True
Go语言代码
package main
import "fmt"
func solution(n int, a []int) []int {
queue := []int{}
for len(a) > 0 {
// 将第一个元素添加到 queue
queue = append(queue, a[0])
a = a[1:]
// 如果 a 中还剩下至少一个元素,将下一个元素放到 a 的末尾
if len(a) > 1 {
a = append(a, a[0])
a = a[1:]
}
}
return queue
}
func main() {
fmt.Println(fmt.Sprintf("%v", solution(5, []int{5, 3, 2, 1, 4})) == fmt.Sprintf("%v", []int{5, 2, 4, 1, 3}))
fmt.Println(fmt.Sprintf("%v", solution(4, []int{4, 1, 3, 2})) == fmt.Sprintf("%v", []int{4, 3, 1, 2}))
fmt.Println(fmt.Sprintf("%v", solution(6, []int{1, 2, 3, 4, 5, 6})) == fmt.Sprintf("%v", []int{1, 3, 5, 2, 6, 4}))
}