当前位置:   article > 正文

「数组」Knuth洗牌算法|C++random库简单介绍 / LeetCode 384(C++)

「数组」Knuth洗牌算法|C++random库简单介绍 / LeetCode 384(C++)

给你一个整数数组 nums ,设计算法来打乱一个没有重复元素的数组。打乱后,数组的所有排列应该是 等可能 的。

实现 Solution class:

  • Solution(int[] nums) 使用整数数组 nums 初始化对象
  • int[] reset() 重设数组到它的初始状态并返回
  • int[] shuffle() 返回数组随机打乱后的结果

示例 :

输入
["Solution", "shuffle", "reset", "shuffle"]
[[[1, 2, 3]], [], [], []]
输出
[null, [3, 1, 2], [1, 2, 3], [1, 3, 2]]

思路

有一个操作,对任意一个元素都可能发生,如果每个元素被操作的概率是相等的,那么这个操作才能公平的进行。

对于数组(长度为len)中每个数字,我们想方法将其中任意一个元素用1/len的概率(等可能)抽出来,然后len--,直到清空数组。我们将元素以拿出的先后顺序为依据形成一个排列,这就是一个公平的随机的排列。

Knuth算法就是一个以此过程对数组进行随机化操作。

算法过程

先介绍C++random(#include <random>)库实现随机数的两个对象。

std::random_device,真随机数类,直接从机器设备中选一个数出来,速度较慢。

std::mt19937,是一个基于32位的梅森旋转算法的对象,生成一个伪随机数,速度较快。

std::random_device rd;实现了一个rd对象。此后每次调用rd()就会获得一个随机数。

std::mt9937 mt(rd()),从rd()调一个随机数作为种子实现了一个mt对象。此后每次调用mt()就会获得一个随机数。

在实际执行Knuth算法中,我们不需要真实取出一个元素,而是只需要初始化i=len-1,从前i+1个数(0,1,2,...i)随机选一个与第i个位置交换即可。

  1. //以------表示随机范围,以*表示取到
  2. i 0 1 2 3 4
  3. nums[i] 9 8 7 6 5
  4. i
  5. ----*----
  6. nums[i] 9 8 5 6 7
  7. i
  8. ----*--
  9. nums[i] 9 8 6 5 7
  10. i
  11. --*--
  12. nums[i] 9 6 8 5 7
  13. i
  14. --*
  15. nums[i] 9 6 8 5 7
  16. i
  17. *
  18. nums[i] 9 6 8 5 7
  1. std::mt19937 mt;
  2. void Knuth(vector<int>&vec){
  3. const int len=vec.size();
  4. for(int i=len-1;i>0;i--)
  5. swap(vec[mt()%(i+1)], vec[i]);
  6. //取余操作+1是为了能取到i,因为第i个位置也在备选行列,自己与自己交换也在公平随机之内
  7. }

Code

  1. class Solution {
  2. private:
  3. vector<int> val;
  4. mt19937 mt;
  5. const int len;
  6. public:
  7. Solution(vector<int>& nums) : val(nums), len(nums.size()){};
  8. vector<int> reset() { return val; }
  9. vector<int> shuffle() {
  10. vector<int> ans(val);
  11. Knuth(ans);
  12. return ans;
  13. }
  14. void Knuth(vector<int>& vec) {
  15. for (int i = len - 1; i > 0; i--)
  16. swap(vec[mt() % (i+1) ], vec[i]);
  17. }
  18. };
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/酷酷是懒虫/article/detail/927469
推荐阅读
相关标签
  

闽ICP备14008679号