每日一题做题记录,参考官方和三叶的题解

文章目录

  • 题目要求
  • 思路一:模拟、哈希表
    • Java
    • C++
  • 思路二:水塘抽样(蓄水池抽样)
    • Java
    • C++
  • 总结

题目要求

思路一:模拟、哈希表

把数组内容整理一下放哈希表,然后从哈希表取值随机返回。
哈希表存的内容是数组元素和它对应的所有下标。

Java

class Solution {Map<Integer, List<Integer>> map;Random ran;public Solution(int[] nums) {map = new HashMap<Integer, List<Integer>>();ran = new Random();for(int i = 0; i < nums.length; ++i) {map.putIfAbsent(nums[i], new ArrayList<Integer>()); // 相同元素放一起map.get(nums[i]).add(i); // 存下标}}public int pick(int target) {List<Integer>idx = map.get(target); // 取下标return idx.get(ran.nextInt(idx.size()));}
}
  • 时间复杂度:初始化为O(n)O(n)O(n),pick函数为O(1)O(1)O(1)
  • 空间复杂度:O(n)O(n)O(n)

C++

class Solution {unordered_map<int, vector<int>> map;
public:Solution(vector<int>& nums) {for(int i = 0; i < nums.size(); ++i)map[nums[i]].push_back(i); // 相同元素下标放一起}int pick(int target) {auto &idx = map[target]; // 取下标return idx[rand() % idx.size()];}
};
  • 时间复杂度:初始化为O(n)O(n)O(n),pick函数为O(1)O(1)O(1)
  • 空间复杂度:O(n)O(n)O(n)

思路二:水塘抽样(蓄水池抽样)

降低空间复杂度,边读边取,适用于长长长文件读取处理。

  • 遍历numsnumsnums,每次遇到targettargettarget元素都选择性更新结果。
  • 设当前为第cntcntcnt次,选择方法为产生[0,cnt)[0,cnt)[0,cnt)内的一个随机整数ranranran:
    • 若ran=0ran=0ran=0,更新结果为当前元素在数组中的下标(不是cntcntcnt);
    • 若ran≠0ran\ne 0ran​=0:不更新结果。

这个选择方法是怎么保证返回每个下标概率相同的呢?
P(第i个target元素下标成为结果)\quad P(第i个target元素下标成为结果)P(第i个target元素下标成为结果)
P(rani=0)×P(rani+1≠0)×⋯×P(rank≠0)\quad P(ran_i=0)\times P(ran_{i+1}\ne 0)\times \dots\times P(ran_k\ne 0)P(rani​=0)×P(rani+1​​=0)×⋯×P(rank​​=0)
=1i×(1−1i+1)×⋯×(1−1k)=\frac{1}{i}\times(1-\frac{1}{i+1})\times\dots\times(1-\frac{1}{k})=i1​×(1−i+11​)×⋯×(1−k1​)
=1i×ii+1×⋯×k−1k=\frac{1}{i}\times\frac{i}{i+1}\times\dots\times\frac{k-1}{k}=i1​×i+1i​×⋯×kk−1​
=1k=\frac{1}{k}=k1​
注:raniran_irani​指第iii轮中选择的随机数。

Java

class Solution {int[] nums;Random ran;public Solution(int[] nums) {this.nums = nums;ran = new Random();}public int pick(int target) {int res = 0;for(int i = 0, cnt = 0; i < nums.length; ++i) {if(nums[i] == target) {++cnt; // 第cnt个targetif(ran.nextInt(cnt) == 0)res = i;}}return res;}
}
  • 时间复杂度:初始化为O(1)O(1)O(1),pick函数为O(n)O(n)O(n)
  • 空间复杂度:O(1)O(1)O(1)

C++

class Solution {vector<int> &nums;
public:Solution(vector<int>& nums) : nums(nums) {}int pick(int target) {int res;for(int i = 0, cnt = 0; i < nums.size(); ++i) {if(nums[i] == target) {++cnt; // 第cnt个targetif(rand() % cnt == 0)res = i;}}return res;}
};
  • 时间复杂度:初始化为O(1)O(1)O(1),pick函数为O(n)O(n)O(n)
  • 空间复杂度:O(1)O(1)O(1)

总结

快乐题目+1,学了新的抽样方法,可以用来处理不定长的巨大数据流,还能保证对每个数的抽取概率一致。

欢迎指正与讨论!

JavaC++题解与拓展——leetcode398.随机数索引【水塘抽样学习】相关推荐

  1. JavaC++题解与拓展——leetcode728.自除数【跳出多层循环,vector at】

    每日一题做题记录,参考官方和三叶的题解 目录 题目要求 思路一:模拟 Java out C++ Python3 思路二:二分 Java C++ vector 思路三:哈希表 Java C++ 总结 题 ...

  2. JavaC++题解与拓展——leetcode1823.找出游戏的获胜者【约瑟夫环】

    每日一题做题记录,参考官方和三叶的题解 目录 题目要求 思路一:模拟 Java C++ 思路二:递归 Java C++ 思路三:迭代 Java C++ Rust 总结 题目要求 [这个问题似乎叫做约瑟 ...

  3. JavaC++题解与拓展——leetcode310.最小高度树【复习链式前向星】

    每日一题做题记录,参考官方和三叶的题解 目录 题目要求 思路一:动态规划 Java 链式前向星 C++ 思路二:拓扑排序+BFS Java C++ 总结 题目要求 思路一:动态规划 遍历整个图,当前遍 ...

  4. JavaC++题解与拓展——leetcode812.最大三角形面积【么的新知识】

    每日一题做题记录,参考官方和三叶的题解 目录 题目要求 思路:枚举 Java C++ Rust 总结 题目要求 思路:枚举 兜兜转转考虑了一圈,结果发现是暴力模拟-- Java class Solut ...

  5. leetcode刷题记录-398. 随机数索引

    前言 今天的题目为中等,跟之前碰到过的一道题思路很相似,利用map表来空间换时间,以此来做到节省时间复杂度. 每日一题 今天的题目是 398. 随机数索引,难度为中等 给你一个可能含有 重复元素 的整 ...

  6. 【PATB1041】考试座位号(题解+拓展)

    [PATB1041]考试座位号(题解+拓展) 原题 题目 输入格式 输出格式 输入样例 输出样例 代码及思路 拓展(通过准考证号找另两个号) 原题 题目 每个 PAT 考生在参加考试时都会被分配两个座 ...

  7. 398. 随机数索引(哈希表预处理 Or 蓄水池抽样)

    文章目录 Question Ideas 1.Answer( Java ) `⚡️ getOrDefault(Object key, V defaultValue)` Code①( HashMap 实现 ...

  8. Java实现 LeetCode 398 随机数索引

    398. 随机数索引 给定一个可能含有重复元素的整数数组,要求随机输出给定的数字的索引. 您可以假设给定的数字一定存在于数组中. 注意: 数组大小可能非常大. 使用太多额外空间的解决方案将不会通过测试 ...

  9. 398. 随机数索引 ( 设计 )

    LeetCode:398. 随机数索引 要求返回 target 在数组中随机的一个下标 留意,这个数组不是有序的,有序的话使用 二分查找. 这里无序的, 直接保存相同元素的下标,然后随机返回 AC C ...

最新文章

  1. 【bzoj2751】[HAOI2012]容易题(easy) 数论,简单题
  2. VLAN TRUNK 链路聚合 网络层路由器
  3. 二叉树的遍历实现-2(三级)
  4. window.onbeforeunload() 事件调用ajax的解决方法
  5. BZOJ 2440 完全平方数(莫比乌斯-容斥原理)
  6. Android 面向切面编程-aspjectj应用
  7. php 压缩js css文件,PHP实现动态压缩js与css文件的方法
  8. Python之面向对象的程序设计
  9. apache tuscany(一)
  10. jQuery.qrcode 生成二维码,并使用 jszip、FileSaver 下载 zip 压缩包至本地。
  11. 点餐系统ip地址_教你一步一步做无线点餐项目(登录篇)
  12. 采访:新浪微博架构师兼首席PHP技术顾问惠新宸谈PHP的架构与发展
  13. 【历史上的今天】6 月 26 日:EDSAC 计算机之父诞生;B 站成立;Skype 创始人出生
  14. python中常用于输出信息的语句函数是print括号_第十四课我们研究一下常用的print()函数,翻看了一下Python宝典...
  15. linux获取网卡协议地址,读取linux下的网络设备的mac地址与发送原始数据包 (2011-11-23 20:11)...
  16. IT企业内部系统运营推广的六种方法
  17. 矩阵与矩阵的乘法运算
  18. Android应用启动之从Launcher拉起APP(三)
  19. 项目数据字典数据导入导出
  20. Prefix-Tuning: Optimizing Continuous Prompts for Generation翻译

热门文章

  1. Spring Autowire自动装配(转http://lep1985520.blog.163.com/blog/static/56600480200901441338486/)
  2. java 废弃方法_在Java中使用Deprecated方法或类是错误的吗?
  3. 困在双11“流量仓”的小红书,能否撑起200亿美元估值?
  4. Erlang并发编程(五) --- bigwig
  5. 天玑9000和骁龙888plus哪个好
  6. 微信吸粉技巧之:微社区
  7. HTTP状态代码2XX、3XX、4XX、5XX分析
  8. 论文阅读:ICCV2021 TransReID: Transformer-based Object Re-Identifification
  9. 前台jQuery实现图片轮播
  10. 一个游戏创业者如何跳出模式