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

130 阅读3分钟

题目介绍

问题描述

小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]

思路描述

初步思考

第一次想的就题目中要求的是播放歌单中的第一首歌,播放后将其从歌单中移除,然后就会判断一下目前是否还存在歌曲。如果目前存在歌曲,注意如果目前还存在歌曲,那么就需要把目前存在的歌曲移动到最后(这里需要注意好,当时就是没有注意到这个问题,从而导致自己一开始没有一次run完代码),这里需要移除上一首歌单后,还需要再移动一次,然后一直到最后一首歌完成上述的步骤。

细节思考

一开始自己想的是用一个队列进行维护,由于是一端出,一端入的情况,所以很容易想到是用双端队列。一开始自己很久没有用队列了,失误的使用为优先队列priority_queue,其实用优先队列的情况是在于一些有着优先级的场景,这样可以使用优先队列加上pair这种数据结构来进行刷题构建。后面等着自己醒悟过来才发现是要使用双端队列,这种双端队列在CPP中是< deque>基本的操作其实跟vector数组的使用方法非常的类似,可以控制队列两端的数据结构进行输入和输出,双端都可以操作,那么我们针对这个题目就可以很快解决了。只需要把题目中要求的数组数据输入到一个双端队列进行维护,每一次移除歌曲就从队列的左边进行出队,进行歌曲的调整就把数据从左边移除,从队列的右边移入。再放入到一个循环语句中进行判断,当循环进行时每一步的操作记录到一个vector中,那么这个问题就解决了。最后返回这个结果就可以。 直接上代码!

代码

#include <deque>
#include <iostream>
#include <vector>

std::vector<int> solution(int n, std::vector<int> a) {
  // write code here
  std::vector<int> res;
  std::deque<int> myQueue(a.begin(), a.end());
  while (!myQueue.empty()) {
    res.push_back(myQueue.front());
    myQueue.pop_front();
    if (!myQueue.empty()) {
      int t = myQueue.front();
      myQueue.pop_front();
      myQueue.push_back(t);
    }
  }
  return res;
}

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;
}