问题解析
问题描述
小R有一个特殊的随机播放规则。他首先播放歌单中的第一首歌,播放后将其从歌单中移除。如果歌单中还有歌曲,则会将当前第一首歌移到最后一首。这个过程会一直重复,直到歌单中没有任何歌曲。
例如,给定歌单 [5, 3, 2, 1, 4],真实的播放顺序是 [5, 2, 4, 1, 3]。
保证歌曲中的id两两不同。
问题描述
好的,让我们来逐步解决这个问题。首先,我们需要理解题目描述中的播放规则:
- 播放歌单中的第一首歌,并将其从歌单中移除。
- 如果歌单中还有歌曲,则将当前第一首歌移到最后一首。
- 重复上述步骤,直到歌单中没有任何歌曲。
为了实现这个逻辑,我们可以使用一个队列(
std::queue)来模拟歌单的操作。队列的特性是先进先出(FIFO),非常适合这个场景。
代码提示
- 初始化队列:将输入的歌单数组转换为一个队列。
- 模拟播放过程:
- 从队列中取出第一首歌(即队列的头部元素)。
- 如果队列不为空,将当前队列的头部元素移到队列的尾部。
- 记录播放顺序:将每次取出的歌曲ID记录到一个结果数组中。
代码框架
#include <iostream>
#include <vector>
#include <queue>
std::vector<int> solution(int n, std::vector<int> a) {
std::vector<int> result; // 用于存储播放顺序
std::queue<int> playlist; // 用于模拟歌单
// 将歌单数组转换为队列
for (int song : a) {
playlist.push(song);
}
while (!playlist.empty()) {
// 取出当前第一首歌
int currentSong = playlist.front();
playlist.pop();
result.push_back(currentSong);
// 如果队列不为空,将当前第一首歌移到最后一首
if (!playlist.empty()) {
int nextSong = playlist.front();
playlist.pop();
playlist.push(nextSong);
}
}
return result;
}
int main() {
std::vector<int> result1 = {5, 2, 4, 1, 3};
std::vector<int> result2 = {4, 3, 1, 2};
std::vector<int> result3 = {1, 3, 5, 2, 6, 4};
std::cout << (solution(5, {5, 3, 2, 1, 4}) == result1) << std::endl;
std::cout << (solution(4, {4, 1, 3, 2}) == result2) << std::endl;
std::cout << (solution(6, {1, 2, 3, 4, 5, 6}) == result3) << std::endl;
}
关键步骤解释
-
初始化队列:
std::queue<int> playlist; for (int song : a) { playlist.push(song); } -
模拟播放过程:
while (!playlist.empty()) { int currentSong = playlist.front(); playlist.pop(); result.push_back(currentSong); if (!playlist.empty()) { int nextSong = playlist.front(); playlist.pop(); playlist.push(nextSong); } }
队列特性
队列:队列也是一种特殊的线性表,与栈不同的是,栈的插入和弹出都是在栈顶,而队列的入队是在表尾(队尾),出队是在表头(队头)。
特点是先进先出(First In First Out),头删尾插
这个题目比较基础,但是在情景建模上有很强借鉴意义