9.5Shuffle an Array随机与取样
题目描述
给定一个数组,要求实现两个指令函数,第一个函数"shuffle"可以随机打乱这个数组,第二个函数"reset"可以恢复原来的顺序
输入输出样例
Input :nums = [1, 2, 3], actions: ["shuffle", "shuffle", "reset"]
Output:[[2,1,3], [3,2,1],[1,2,3]]
题解
采用景点的Fisher-Yates洗牌算法,原理是通过随机交换位置来实现随机打乱,有正向和反向两种写法,实现很简单。
cpp
#include <iostream>
#include <vector>
using namespace std;
class Solution {
vector<int> origin;
public:
Solution(vector<int> nums) :origin(std::move(nums)) {}
vector<int> reset() {
return origin;
}
vector<int> shuffle() {
if (origin.empty()) return {};
vector<int> shuffled(origin);
int n = origin.size();
//反向洗牌
for (int i = n - 1; i >= 0; --i) {
swap(shuffled[i], shuffled[rand() % (i + 1)]);
}
//正向洗牌(跟反向效果一样)
//for (int i = 0; i < n; ++i) {
// int pos = rand() % (n - i);
// swap(shuffled[i], shuffled[i + pos]);
//}
return shuffled;
}
};
void printVector(const vector<int>& vec) {
cout << "[";
for (int i = 0; i < vec.size(); ++i) {
cout << vec[i];
if (i != vec.size() - 1) cout << ",";
}
cout << "]" << endl;
}
int main() {
// 1. 初始化原始数组(对应样例输入nums = [1,2,3])
vector<int> nums = { 1, 2, 3 };
// 2. 创建Solution对象(注意:Solution solution(); 是函数声明,不是对象创建!)
Solution solution(nums);
// 3. 设置随机数种子(否则每次运行shuffle结果都一样)
srand((unsigned)time(NULL));
// 4. 模拟样例操作:shuffle → shuffle → reset
cout << "第一次shuffle结果:";
printVector(solution.shuffle()); // 输出随机打乱的数组(如[2,1,3])
cout << "第二次shuffle结果:";
printVector(solution.shuffle()); // 输出另一个随机打乱的数组(如[3,2,1])
cout << "reset结果:";
printVector(solution.reset()); // 输出原始数组[1,2,3]
return 0;
}