【LeetCode】384. Shuffle an Array 解题报告(Python & C++)
作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/
题目地址:https://leetcode.com/problems/shuffle-an-array/description/
题目描述
Shuffle a set of numbers without duplicates.
Example:
// Init an array with set 1, 2, and 3.
int[] nums = {1,2,3};
Solution solution = new Solution(nums);
// Shuffle the array [1,2,3] and return its result. Any permutation of [1,2,3] must equally likely to be returned.
solution.shuffle();
// Resets the array back to its original configuration [1,2,3].
solution.reset();
// Returns the random shuffling of array [1,2,3].
solution.shuffle();
题目大意
定义两个函数,shuffle函数能把数组随机打乱,reset函数能返回初始数组。
解题方法
库函数
直接调用python的random.shuffle就行了。C++也有std::random_shuffle()函数。
注意都是原地打乱。
Python代码如下:
import random
class Solution(object):
def __init__(self, nums):
"""
:type nums: List[int]
"""
self.nums = nums
def reset(self):
"""
Resets the array to its original configuration and return it.
:rtype: List[int]
"""
return self.nums
def shuffle(self):
"""
Returns a random shuffling of the array.
:rtype: List[int]
"""
nums_s = self.nums[:]
random.shuffle(nums_s)
return nums_s
# Your Solution object will be instantiated and called as such:
# obj = Solution(nums)
# param_1 = obj.reset()
# param_2 = obj.shuffle()
C++代码如下:
class Solution {
private:
vector<int> nums_;
vector<int> toshuffle_;
public:
Solution(vector<int> nums) {
nums_ = nums;
toshuffle_ = nums;
}
/** Resets the array to its original configuration and return it. */
vector<int> reset() {
toshuffle_ = nums_;
return nums_;
}
/** Returns a random shuffling of the array. */
vector<int> shuffle() {
random_shuffle(toshuffle_.begin(), toshuffle_.end());
return toshuffle_;
}
};
/**
* Your Solution object will be instantiated and called as such:
* Solution obj = new Solution(nums);
* vector<int> param_1 = obj.reset();
* vector<int> param_2 = obj.shuffle();
*/
Fisher–Yates 洗牌
新学习了Fisher–Yates shuffle 洗牌算法。
Fisher–Yates shuffle 的原始版本,最初描述在 1938 年的 Ronald Fisher 和 Frank Yates 写的书中,书名为《Statistical tables for biological, agricultural and medical research》。他们使用纸和笔去描述了这个算法,并使用了一个随机数表来提供随机数。它给出了 1 到 N 的数字的的随机排列,具体步骤如下:
- 写下从 1 到 N 的数字
- 取一个从 1 到剩下的数字(包括这个数字)的随机数 k
- 从低位开始,得到第 k个数字(这个数字还没有被取出),把它写在独立的一个列表的最后一位
- 重复第 2步,直到所有的数字都被取出
- 第 3 步写出的这个序列,现在就是原始数字的随机排列
已经证明如果第 2 步取出的数字是真随机的,那么最后得到的排序一定也是。
洗牌的过程可以看看这个文章,看一遍一定就懂!https://gaohaoyang.github.io/2016/10/16/shuffle-algorithm/
这个算法的一句话总结:依次遍历列表中的每一位,并将这一位与其后面的随机一位交换顺序。
import random
class Solution(object):
def __init__(self, nums):
"""
:type nums: List[int]
"""
self.nums = nums
def reset(self):
"""
Resets the array to its original configuration and return it.
:rtype: List[int]
"""
return self.nums
def shuffle(self):
"""
Returns a random shuffling of the array.
:rtype: List[int]
"""
nums_s = self.nums[:]
_len = len(self.nums)
for i in xrange(_len):
rand = random.randrange(i, _len)
nums_s[i], nums_s[rand] = nums_s[rand], nums_s[i]
return nums_s
# Your Solution object will be instantiated and called as such:
# obj = Solution(nums)
# param_1 = obj.reset()
# param_2 = obj.shuffle()
水塘抽样
另外一个抽样算法叫做水塘抽样,其本来的目的是在大数据流中的随机抽样问题,即:当内存无法加载全部数据时,如何从包含未知大小的数据流中随机选取k个数据,并且要保证每个数据被抽取到的概率相等。
- 当K = 1时,数据流中第i个数被保留的概率为 1/i。只要采取这种策略,只需要遍历一遍数据流就可以得到采样值,并且保证所有数被选取的概率均为 1/N 。
- 当K > 1时,对于前k个数,我们全部保留,对于第i(i>k)个数,我们以K/i的概率保留第i个数,并以 1/K的概率与前面已选择的k个数中的任意一个替换。
证明过程:https://zhuanlan.zhihu.com/p/29178293
至于这个题的随机打乱,其实就是在长度K的数据中,随机选K个数字的问题,方法变成了和Fisher–Yates 洗牌完全一样了,一句话总结就是:依次遍历列表中的每一位,并将这一位与其后面的随机一位交换顺序。
C++代码如下:
class Solution {
private:
vector<int> nums_;
public:
Solution(vector<int> nums) {
nums_ = nums;
}
/** Resets the array to its original configuration and return it. */
vector<int> reset() {
return nums_;
}
/** Returns a random shuffling of the array. */
vector<int> shuffle() {
vector<int> res = nums_;
for (int i = 0; i < res.size(); ++i) {
int t = i + rand() % (res.size() - i);
swap(res[i], res[t]);
}
return res;
}
};
/**
* Your Solution object will be instantiated and called as such:
* Solution obj = new Solution(nums);
* vector<int> param_1 = obj.reset();
* vector<int> param_2 = obj.shuffle();
*/
日期
2018 年 2 月 27 日
2019 年 2 月 22 日 —— 这周结束了
【LeetCode】384. Shuffle an Array 解题报告(Python & C++)的更多相关文章
- leetcode 384. Shuffle an Array
384. Shuffle an Array c++ random函数:https://www.jb51.net/article/124108.htm rand()不需要参数,它会返回一个从0到最大随机 ...
- [LeetCode] 384. Shuffle an Array 数组洗牌
Shuffle a set of numbers without duplicates. Example: // Init an array with set 1, 2, and 3. int[] n ...
- Java [Leetcode 384]Shuffle an Array
题目描述: Shuffle a set of numbers without duplicates. Example: // Init an array with set 1, 2, and 3. i ...
- 【LeetCode】26. Remove Duplicates from Sorted Array 解题报告(Python&C++&Java)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 双指针 日期 [LeetCode] https:// ...
- 【LeetCode】525. Contiguous Array 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 累积和 日期 题目地址:https://leetco ...
- 【LeetCode】896. Monotonic Array 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...
- 【LeetCode】932. Beautiful Array 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 构造法 递归 相似题目 参考资料 日期 题目地址:h ...
- 【LeetCode】189. Rotate Array 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 切片 递归 日期 题目地址:https://leet ...
- 【LeetCode】62. Unique Paths 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址:https://leetcode.com/problems/unique-pa ...
随机推荐
- ggplot 局部放大
需要安装包:ggforce,下面以R自带数据做局部放大演示. require(ggplot2) require(ggforce) require(reshape2) data(CO2) co2< ...
- UE4类型数据自动注册
Version:4.26.2 UE4 C++工程名:MyProject 在<宏GENERATED_BODY做了什么?>中,简单分析了GENERATED_BODY宏给一个简单的.继承自UOb ...
- 利用抖音Cookie充值接口提取支付链接,个人调起原生微信h5支付宝h5支付
最近开始搞一些个人支付通道的开发,方便个人不用和第三方平台签约就能收款,省去很多流程手续的成本. 然后翻了一下网上并没有太多现成的技术教程,只能自己研究着搞了. 这次要分享的是利用抖音的充值接口,去分 ...
- 零基础学习java------day18------properties集合,多线程(线程和进程,多线程的实现,线程中的方法,线程的声明周期,线程安全问题,wait/notify.notifyAll,死锁,线程池),
1.Properties集合 1.1 概述: Properties类表示了一个持久的属性集.Properties可保存在流中或从流中加载.属性列表中每个键及其对应值都是一个字符串 一个属性列表可包含另 ...
- Linux学习 - 数值运算
1 declare 声明变量类型 declare [+/-] [选项] 变量名 - 给变量设定类型属性 + 取消变量的类型属性 -i 将变量声明为整数型 -x 将变量声明为环境变量(同export) ...
- Can namespaces be nested in C++?
In C++, namespaces can be nested, and resolution of namespace variables is hierarchical. For example ...
- html框架frame iframe
框架 通过使用框架,你可以在同一个浏览器窗口中显示不止一个页面.没分HTML文档称作一个框架. 缺点: 开发人员必须同时跟踪更多的HTML文档 很难打印整张页面 框架结构标签(<frameset ...
- 大数据处理系列之(一)Java线程池使用
前言:最近在做分布式海量数据处理项目,使用到了java的线程池,所以搜集了一些资料对它的使用做了一下总结和探究, 前面介绍的东西大多都是从网上搜集整理而来.文中最核心的东西在于后面两节无界队列线程池和 ...
- Springboot Oauth2 集成Swagger2权限验证实战
Swagger是什么?能干什么?在这就不展开讲解了.本文主要讲解如何集成OAuth2的Password模式权限验证,验证接口是否具有权限. 引入依赖 <dependency> <gr ...
- shell脚本采集系统cpu、内存、磁盘、网络信息
有不少朋友不知道如何用shell脚本采集linux系统相关信息,包括cpu.内存.磁盘.网络等信息,这里脚本小编做下讲解,大家一起来看看吧. 一.cpu信息采集 1),采集cpu使用率采集算法:通过/ ...