一题算法|求随机数索引
发布日期:2021-09-18 10:05:28 浏览次数:12 分类:技术文章

本文共 2131 字,大约阅读时间需要 7 分钟。

题目描述

给定一个可能含有重复元素的整数数组,要求随机输出给定的数字的索引。 您可以假设给定的数字一定存在于数组中。

注意

数组大小可能非常大。 使用太多额外空间的解决方案将不会通过测试。

题目示例

int[] nums = new int[] {
1,2,3,3,3};Solution solution = new Solution(nums);// pick(3) 应该返回索引 2,3 或者 4。每个索引的返回概率应该相等。solution.pick(3);// pick(1) 应该返回 0。因为只有nums[0]等于1。solution.pick(1);

这题目中有一个地方需要注意,每一个索引返回的概率都是相同的。比较笨的方法就是将与 target 相等的元素存放到一个中间集合中,最后从中间集合随机取一个。第二种办法就是利用蓄水池抽样法来解决这个问题。

解法一:使用中间集合

我们先从头到尾遍历数组,将与 target 相等元素的索引,集中存储到中间集合 list 中,最后再从中间集合中随机返回一个元素索引。

1、解题代码:

class Solution {
private int[] nums; public Solution(int[] nums) {
this.nums = nums; } public int pick(int target) {
// 开辟一个中间集合 List
list = new ArrayList<>(); for (int i = 0; i < nums.length; i++) {
// 找出与target相等的元素 if (nums[i] == target) {
list.add(i); } } // 如果只存在一个,就直接返回 if (list.size() == 1) return list.get(0); // 如果有两个以上,随机取一个 return getRandomIndex(list); } /** * 随机给出下标 * * @param list 给定元素的索引集合 * @return */ public int getRandomIndex(List
list) {
return list.get(new Random().nextInt(list.size())); }}

复杂度分析

时间复杂度:需要遍历一次数组,所以时间复杂度是O(N)

空间复杂度:使用了 ArrayList ,ArrayList 的大小与数组有关,所以空间复杂度为O(N)

解法二:蓄水池抽样算法

这是我在 leetcode 上看到的解法,蓄水池抽样算法好像是一种专业的算法,关于算法的详情,大家就自行百度,我也不是太清楚,这里我就简单的描述:给定一个数据流,数据流长度N很大,且N直到处理完所有数据之前都不可知,请问如何在只遍历一遍数据(O(N))的情况下,能够随机选取出m个不重复的数据。符合我们的题意,这里我就直接给出解题代码,具体的也不是很清楚,不过刷题不就是扩宽思维吗?

1、解题代码

class Solution {
private int[] nums; public Solution(int[] nums) {
this.nums = nums; } public int pick(int target) {
// 返回下标,没找到就返回-1 int index = -1; // 记录查找到的个数 int count = 0; for (int i = 0; i < nums.length; i++) {
if (nums[i] == target) {
count++; // 随机返回,new Random().nextInt() % count == 0 作为概率 if (new Random().nextInt() % count == 0) index = i; } } return index; }}

复杂度分析

时间复杂度:需要遍历一次数组,所以时间复杂度是O(N)

空间复杂度:没有使用新的集合,所以空间复杂度为O(1)

最后

欢迎扫码关注微信公众号:「平头哥的技术博文」,和平头哥一起学习,一起进步。

平头哥的技术博文

转载地址:https://blog.csdn.net/z694644032/article/details/103700178 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:熟悉这几道 Redis 高频面试题,面试不用愁
下一篇:一题算法|求最长和谐子序列

发表评论

最新留言

第一次来,支持一个
[***.219.124.196]2024年04月05日 15时34分45秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

【Leetcode刷题篇】leetcode312 戳气球 2019-04-26
前后端分离如何使用spring boot处理跨域请求 2019-04-26
【Leetcode刷题篇】leetcode283 移动零 2019-04-26
【Leetcode刷题篇】leetcode611 有效三角形的个数 2019-04-26
【Leetcode刷题篇】leetcode26 删除排序数组中的重复项 2019-04-26
【大话Java面试】-如何通俗易懂的理解Redis的分布式寻址算法hash slot? 2019-04-26
【大话Java面试】-如何通俗易懂的理解单例模式? 2019-04-26
【大话Java面试】请列出Java中几个常用的设计模式? 2019-04-26
【大话Java面试】-如何通俗易懂的理解Java异常以及Java异常处理? 2019-04-26
【大话Mysql面试】-Mysql的索引为什么要使用B+树,而不是B树,红黑树等之类? 2019-04-26
【大话Mysql面试】-如何通俗易懂的了解Mysql的索引最左前缀匹配原则 2019-04-26
【大话Mysql面试】-MYSQL的两种存储引擎MyISAM与InnoDB的区别是什么? 2019-04-26
【大话Mysql面试】-InnoDB可重复读隔离级别下如何避免幻读?MVCC和next-key是什么 2019-04-26
【大话Mysql面试】-Mysql如何恢复数据?如何进行主从复制?Binlog日志到底是什么? 2019-04-26
理解String.intern()和String类常量池疑难解析例子 2019-04-26
python flask打造前后端分离的口罩检测 2019-04-26
【大话Mysql面试】-MySQL基础知识 2019-04-26
【大话Mysql面试】-MySQL数据类型有哪些 2019-04-26
【大话Mysql面试】-MySQL数据引擎 2019-04-26
【大话Mysql面试】-常见SQL语句书写 2019-04-26