lc算法:随机篇

528. 按权重随机选择
给定一个正整数数组 w ,其中 w[i] 代表下标 i 的权重(下标从 0 开始),请写一个函数 pickIndex ,它可以随机地获取下标 i,选取下标 i 的概率与 w[i] 成正比。
法1:前缀和+二分

470. 用 Rand7() 实现 Rand10()
根据平均生成1-7的API实现平均生成1-10的API
法:根据两次生成的值以二维矩阵的形式采用拒绝采用的算法

530. 打乱数组
给你一个整数数组 nums ,设计算法来打乱一个没有重复元素的数组。
实现 Solution class:
Solution(int[] nums) 使用整数数组 nums 初始化对象
int[] reset() 重设数组到它的初始状态并返回
int[] shuffle() 返回数组随机打乱后的结果
优化删除思路:Fisher-Yates
在这里插入图片描述
519. 随机翻转矩阵
给你一个 m x n 的二元矩阵 matrix ,且所有值被初始化为 0 。请你设计一个算法,随机选取一个满足 matrix[i][j] == 0 的下标 (i, j) ,并将它的值变为 1 。所有满足 matrix[i][j] == 0 的下标 (i, j) 被选取的概率应当均等。
尽量最少调用内置的随机函数,并且优化时间和空间复杂度。
实现 Solution 类:
Solution(int m, int n) 使用二元矩阵的大小 m 和 n 初始化该对象
int[] flip() 返回一个满足 matrix[i][j] == 0 的随机下标 [i, j] ,并将其对应格子中的值变为 1
void reset() 将矩阵中所有的值重置为 0

法:Fisher-Yates注意特判

497. 非重叠矩形中的随机点
给定一个由非重叠的轴对齐矩形的数组 rects ,其中 rects[i] = [ai, bi, xi, yi] 表示 (ai, bi) 是第 i 个矩形的左下角点,(xi, yi) 是第 i 个矩形的右上角点。设计一个算法来随机挑选一个被某一矩形覆盖的整数点。矩形周长上的点也算做是被矩形覆盖。所有满足要求的点必须等概率被返回。
在给定的矩形覆盖的空间内的任何整数点都有可能被返回。

法:要么在一个大的空间随机采样,要么序列化所有的点,通过随机访问下标达到随机访问点的效果。此题采用第二种更方便一些。但是不能完全序列化所有的点,因为会导致数组过大,更好的方式是采用前缀和的方式,将每个矩阵的点编号,这样每个矩阵的点编号固定为x~y的连续数字,然后将数组每个元素存储为前面所有矩阵的点数量和,这一步可以二分做加快速度。当找到点所在矩阵后,还得确认点在矩阵中的位置。这一步灵活性大,采用左下角为第一个元素,右上角为最后一个元素,从下到上——>从左往右的顺序给矩阵中元素标号。从而解决这道题。
(用前缀和解决数据量过大问题,使用二分索引元素位置,虽然没有随机读取O(1)好,但性能也足够优秀。总而言之采用的是将矩阵点编号来解决该题)

710. 黑名单中的随机数
同洗牌算法,如果采用拒绝采样,那么速度会比较差,这题采用映射的方法。统一将黑名单的数全部映射到最后一段连续数字,然后每次随机取前面那一段,判断map是否包含,有则把映射的白名单数字返回。这样完全做到了拒绝采样。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值