LeetCode-384-打乱数组
迪丽瓦拉
2024-05-26 08:05:31
0

在这里插入图片描述

1、列表随机

为了能够初始化数组,我们使用nums保存当前的数组,利用orignal保存初始化数组。为了实现等可能随机打乱,考虑到随机数本质上是基于随机数种子的伪随机,我们采用如下的方式实现等可能随机:我们将所有元素压入列表,每次随机选择一个位置上的数字,按顺序将其放入打乱后的数组中,而后我们从列表中删除当前元素。

class Solution {
private:vector nums;vector orignal;
public:Solution(vector &nums) {this->orignal = nums;this->nums = nums;}vector reset() {this->nums = this->orignal;return this->nums;}vector shuffle() {vector shuffled(nums.size());list lst(nums.begin(), nums.end());for (int i = 0; i < nums.size(); ++i) {int j = rand() % (lst.size());auto it = lst.begin();advance(it, j);shuffled[i] = *it;lst.erase(it);}copy(shuffled.begin(), shuffled.end(), nums.begin());return nums;}
};

2、Fisher-Yates 洗牌算法

考虑到方法一中随机打乱的时间复杂度达到O(n2)O(n^2)O(n2),我们可以对随机打乱的方式进行进一步的改进:我们在第i次循环中,在[i,n)[i,n)[i,n)中随机选择一个位置j上的元素将其与位置i上的元素进行交换,如此循环直至n次。这样做能够确保我们在O(n)O(n)O(n)的时间复杂度内实现随机打乱。

class Solution {
private:vector nums;vector orignal;
public:Solution(vector &nums) {this->orignal = nums;this->nums = nums;}vector reset() {return this->orignal;}vector shuffle() {for (int i = 0; i < nums.size(); ++i) {int j = i + rand() % (nums.size() - i);swap(nums[i], nums[j]);}return nums;}
};

上一篇:ISTQB-TM-大纲

下一篇:Android实例仿真之三

相关内容