• LeetCode 384 打乱数组


    题目链接:LeetCode 384 打乱数组

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

    题解:
    参考自LeedCode官方题解
    首先,我们考虑如何随机打乱一个数组。
    不妨设数组\(nums\),其长度为\(n\)。我们可以使用如下方法打乱:

    • 将数组中所有的数都放到数据结构\(waiting\)中,并初始化打乱后的数组\(shuffle\)
    • 循环\(n\)次,在第\(i\)次循环中\((0 \leq i < n)\)
      • \(waiting\)中随机抽取一个数\(num\),将其作为打乱后的数组\(shuffle\)的第\(i\)个元素;
      • \(waiting\)中移除\(num\)

    对于原数组\(nums\)中的数\(num\)来说,被移动到打乱后的数组的第\(i\)个位置的概率为:

    \[p[i]= \left\{ \begin{array}{l} (\frac{n-1}{n} \times \frac{n-2}{n-1} \times ... \times \frac{n-i}{n-i+1}) \times \frac{1}{n-i} = \frac{1}{n}, i>0 \\ \frac{1}{n}, i = 0 \end{array} \right. \]

    因此,对于原数组\(nums\)中的任意一个数,被移动到打乱后的数组的任意一个位置的概率都是相同的。

    class Solution {
    private:
        vector<int> nums;
        vector<int> orgins;
    
    public:
        Solution(vector<int>& nums) {
            this->nums = nums;
            this->orgins.resize(nums.size());
            copy(nums.begin(), nums.end(), orgins.begin());
        }
        
        vector<int> reset() {
            copy(orgins.begin(), orgins.end(), nums.begin());
            return nums;
        }
        
        vector<int> shuffle() {
            vector<int> shuf(orgins.size());
            copy(orgins.begin(), orgins.end(), shuf.begin());
            for (int i = 0; i < orgins.size(); ++i) {
                int index = rand() % shuf.size();
                vector<int>::iterator it = shuf.begin();
                advance(it, index);
                nums[i] = *it;
                shuf.erase(it);
            }
            return nums;
        }
    };
    
  • 相关阅读:
    动手动脑之异常处理
    git一些概念
    jquery each函数使用
    数据库客户端
    plotly.js
    网站跳转汇总
    jquery 实现间隔运行
    学习 在线调试
    Robot限制字典的key大写的class
    Gerrit 相关
  • 原文地址:https://www.cnblogs.com/IzumiSagiri/p/15866421.html
Copyright © 2020-2023  润新知