等概率选取未知长度的链表中的元素

【算法】未知长度序列等概率采样 给一个序列,长度未知,要求从中随机等概率采样出m个元素。 阅读详情

 

有个链表,长度未知,要随机(等概率)选取其中的item

代码如下:
int nmatch = 0;
for ( p=list; p!=NULL; p=p->next ){
    if ( rand() % ++nmatch == 0 ){
        wanted = p;
    }
} 
wanted 即为所求item


命题: 链表中的每个元素的选择概率为1/n,其中n=链表长度
以n为归纳条件
证明如下:
当n=1时,有100%的概率选取第1个item,链表中的每个元素的选择概率为1/1
当n=2时,第一次循环时有100%的概率选取第1个item,第2次循环时有50%的概率选取第2个item(即替换了第1个元素),因此当链表有2个item时,任何一个被选取的概率都是1/2
假设当n=k时,链表中的每个元素的选择概率为1/k
当n=k+1时,将k+1个元素的链表分成两部分(前k个元素组成的链表和第k+1个元素)。由归纳假设,前k次循环可以使链表的前k个元素的每一个被选中的概率为1/k,设前k个元素中的任何一个为i,则选取i的概率为1/k。
最后一次循环的if ( rand() % ++nmatch == 0 ),使得选取第k+1个元素的概率是1/(k+1)。
则在k+1个元素的链表中选取i的概率为1/k-1/k*1/(k+1)=1/(k+1),其中1/k表示前k个元素中选中i的概率,1/k*1/(k+1)表示选中i之后又选了第k+1个元素(即选中的元素i被k+1替换了)。由于i的一般性,则前k个元素的选取概率都为1/(k+1)。从而在有k+1个元素的链表中,每个元素的选取概率都是1/(k+1),得证。

 

深度理解跳跃链表:一种基于概率选择的平衡树 深度理解跳跃链表:一种基于概率选择的平衡树 二叉树是一种常见的数据结构。它支持包括查找、插入、删除等一系列操作。但它有一个致命的弱点,就是当数据的随机性不够时,会导致其树形结构的不平衡,从而直接影响算法的效率。 跳跃链表(Skip List)是1987年才诞生的一种崭新的数据结构,它在进行查找、插入、删除等操作时的期望时间复杂度均为O(logn),有着近乎替代平衡树的本领。而且最重要的一点,就是它的编程复杂度较同类的AVL树,红黑树等要低得多,这使得其无论是在理解还是在推广性上,都有着十分明显的优势。 阅读详情

相关推荐

ERA5数据批量下载

ERA5再分析数据的IDM接管下载

qq_38734327的博客 3034

未知长度链表数据随机抽取问题-蓄水池抽样算法

1. 问题由来 Google曾经有一道非常经典的面试题: 给你一个长度为N的链表。N很大,但你不知道N有多大。你的任务是从这N个元素中随机取出k个元素。你只能遍历这个链表一次。你的算法必须保证取出的元素恰好有k个,且它们是完全随机的(出现概率均等)? 这道题的解法非常多,网上讨论也非常热烈。本文要讨论的是,这个问题是从何而来,有什么实用价值? 自从有了Hadoop之后,该问题便有了新的应用载体。随着数据量的增多,很多数据挖掘算法被转移到MapReduce上实现,而数据挖掘中有个基本的问题是.

細水、長流√的专栏 902

优化Cartographer重定位速度:从子图筛选到参数调优的完整思路

本文详细介绍了优化Cartographer重定位速度的完整方法,从子图筛选到参数调优,帮助工程师在已知初始位姿的前提下将重定位耗时降低50%以上。重点分析了性能瓶颈、子图筛选策略、匹配算法选择及环境自适应的参数优化策略,并通过实战案例展示了显著效果提升。

weixin_28704565的博客 464

给定一个未知长度的整数流,如何随机选取一个数?

方法1. 将整个整数流保存到一个数组中,然后再随机选取。 如果整数流很长,无法保存下来,则此方法不能使用。   方法2. 如果整数流在第一个数后结束,则我们必定会选第一个数作为随机数。 如果整数流在第二个数后结束,我们选第二个数的概率为1/2。我们以1/2的概率用第2个数替换前面选的随机数,得到满足条件的新随机数。 .... 如果整数流在第n个数后结束,我们选第n个数的概率为1/n

elton_xiao的专栏 1463

HCIA-Storage 存储工程师学习笔记——1. 存储技术趋势

文章目录1. 存储技术趋势1.1 数据、信息与数据存储1.2 存储技术的发展①存储架构的发展②存储介质的发展③ 接口协议的发展1.3 存储产品的发展趋势 华为HCIA-Storage认证地址:https://e.huawei.com/cn/talent/#/cert/roadmap 1. 存储技术趋势 1.1 数据、信息与数据存储 什么是数据? ​ 数据是对所有事物的数字表示。 数据的种类? 结构化数据 半结构化数据 非结构化数据 数据的处理周期 ​ 数据处理是人或机器对数据进行的重组或重新排序,

超级大洋葱的博客 2846

StarCCM+ 导入STL几何模型进行仿真

通过 Import Surface Mesh 的方法导入 STL 文件进行仿真

薛定谔的alpha狗 6129

等概率选取随机流中的元素

给定一个输入流,停止时的长度未知(假设无休止的进行下去),如何等概率的获取每一个位置上的元素。 解决:设输入流当前长度为n,以1/n的概率获取当前位置的元素来替代之前获取的元素 可以用归纳法证明: 当队列长度为1时,获取该元素的概率p=1/1 (100%) 当队列长度为2时,获取位置为2元素的概率p=1/2(50%),即以50%的概率替代位置1上的元素,这样每个元素被获取的概率均为50%

山已几的Blog 855

从MFCC到GMM:手把手教你用Python实现说话人识别(附完整代码)

本文详细介绍了如何使用Python实现说话人识别系统,从MFCC特征提取到GMM模型训练,涵盖完整的技术流程和代码示例。通过梅尔频率倒谱系数(MFCC)和高斯混合模型(GMM)的结合,构建高效的说话人识别系统,适用于身份认证和智能交互场景。文章还探讨了从传统方法到深度学习的进阶话题,如i-vector和x-vector技术。

o1p2q3r的博客 200

随机从长度未知的数组中抽取数字,且保证每个元素被抽到的概率相同

昨天面试字节,手写代码之后进一步考查了一道题。面试官让我说一下有什么思路。 题目如下: 有一个函数int getNum(),每运行一次可以从一个数组V[N]里面取出一个数,N未知,当数取完的时候,函数返回NULL。现在要求写一个函数int get(),这个函数运行一次可以从V[N]里随机取出一个数,而这个数必须是符合1/N平均分布的,也就是说V[N]里面任意一个数都有1/N的机会被取出,要求空间复杂度为O(1)。 我当时的思路是如果随机抽取,那么肯定要用到random方法,另外如果不能获得数组长度,那么

书生的日常 1446

AutoSAR从0开始实战 --- 目录

​​​​​​本专栏是全网最真实的AutoSAR实战专栏,博主将从一个0基础小白的身份来讲解AutoSAR工具的配置,以及相应代码的讲解。

wj博客 1728

C++之2048小游戏 第二期

游戏会有初始化、绘制界面、处理输入、更新游戏状态、判断胜负等部分。所以,可能需要一个二维数组来表示4x4的网格,存储每个格子的数值。然后,需要处理键盘输入,尤其是方向键的控制,这可能需要使用EasyX的键盘事件处理函数。然后,关于图形绘制部分,每个格子的大小、颜色、数字的显示都需要设计。不同的数字对应不同的颜色,比如2是浅色,4稍深,以此类推。可能需要一个函数根据数字的值返回对应的颜色,然后在绘制时调用。接下来,处理数字的移动和合并逻辑。这是比较复杂的部分。

Lucky_Glory的博客 805

单次遍历,等概率随机选取问题

问题描述:假设我们有一堆数据(可能在一个链表里,也可能在文件里),数量未知。要求只遍历一次这些数据,随机选取其中的一个元素,任何一个元素被选到的概率相等。O(n)时间,O(1)辅助空间(n是数据总数,但事先不知道)。 引例: 5个人抽5个签,只有一个签意味着“中签”,轮流抽签,从很久很久以前我们就认为这个是非常公平的例子,这个应该不用去怀疑吧。如果怀疑了,好吧,看下面的分析: 分析: 设Ai为第i...

Baymi的博客 883

Open-Sora代码详细解读(1):解读DiT结构

目前开源的DiT视频生成模型不是很多,Open-Sora是开发者生态最好的一个,涵盖了DiT、时空DiT、3D VAE、Rectified Flow、因果卷积等Diffusion视频生成的经典知识点。本篇博客从Open-Sora的代码出发,深入解读背后的原理。

沉迷单车的追风少年 2264

随机选取一个长度为N的链表(N很大)里的K个元素

随机选取一个长度为N的链表(N很大)里的K个元素 - 编程珠玑 给你一个长度为N的链表。N很大,但你不知道N有多大。你的任务是从这N个元素中随机取出k个元素。你只能遍历这个链表一次。你的算法必须保证取出的元素恰好有k个,且它们是完全随机的(出现概率均等)。 解法1:   先选中前k个, 从第k+1个元素到最后一个元素为止, 以k/i (i=k+1, k+2,...,N) 的概率选中第i个元

感悟编程 968

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

水塘抽样算法

给一个未知长度的序列,如何在其中随机地选择k个元素? 第i个元素被选择的概率是1/i,第i+1次不被替换的概率是1 - 1/(i+1),以此类推,相乘就是第i个元素最终被选中的概率,就是1/n。 /* 返回链表中一个随机节点的值 */ int getRandom(ListNode head) { Random r = new Random(); int i = 0, res = 0; ListNode p = head; // while 循环遍历...

qq_37001674的博客 230

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

蓄水池抽样与带面积的蓄水池抽样

蓄水池算法

weixin_41636858的博客 155

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Linked List Random Node

Linked List Random Node Question: 思路: 这道题乍一看, 挺简单的. 没什么难度, 确实,但这题主要是一个解法非常smart. so: generally 3种解法. 前两种不必多说了, 说一下这个第三种解法: reservoir sampling. 这是一个很牛逼的算法。 讲的是如何从infintine number 的data中 随机抽取一个数. 就前提条件是这个 array of number的长度我们是未知的。就是说不知道有多少个数字, 所以在这种情况下. 如果

weixin_44912492的博客 202

Reservoir Sampling

Reservoir Sampling:从N个数中随机抽取k个元素,保证每个元素被选中的概率相等,N不知道有多大。 分析:这个问题称为蓄水池抽样,经典方法: Init : a reservoir with the size: k for(int i = k + 1; i <= N; ++i) { m = random(1, i); if(k >= m) ...

weixin_30821731的博客 146

算法——蓄水池抽样算法

有一个算法可以用于解决上述问题,该算法名称是蓄水池抽样算法。个数,每个数字被选择的概率都是。给定一个数据流,数据流的长度。

qq_43332536的博客 323

等概率选取问题 Random Pick

等概率选取问题要求保证选取的随机性,即

LUCKYOJ 3793

海量数据等概率选取问题

http://www.cnblogs.com/luxiaoxun/archive/2012/09/09/2677267.html

304

在链表中等概率选取元素

1. 在链表中等概率选取一个元素代码:nmatch = 0;for (p = list; p != NULL; p = p->next)    if (rand() % ++nmatch == 0)        selected = p;return selected;解释:对第 k 个节点(从 k=1 开始计数,最大为链表长度n),它被选中的情况是 selected = p;

881

百度面试题——未知长度链表中随机取出其中某一节点的值

题目描述:有一个单向链表的长度未知,怎样从中随机取出一个节点?要求每个节点被选中的概率相等。 解决方法:    遍历一次链表,用一个临时变量pTemp指向返回的节点,设一个计数器iCount统计已遍历的节点个数,然后生成0到iCount-1之间的随机数;若生成的随机数为0,则将pTemp指针替换为当然节点的地址。可以证明对每一个节点,它被选中的概率为1/n,n为链表的长度。     对于第i

a06057329的专栏 3089

Java实现 LeetCode 382 链表随机节点

382. 链表随机节点 给定一个单链表,随机选择链表的一个节点,并返回相应的节点值。保证每个节点被选的概率一样。 进阶: 如果链表十分大且长度未知,如何解决这个问题?你能否使用常数级空间复杂度实现? 示例: // 初始化一个单链表 [1,2,3]. ListNode head = new ListNode(1); head.next = new ListNode(2); head.next.nex...

南 墙 1万+
上一篇: 编程珠玑(2)
下一篇: 文本处理的一些C C++ STL函数
ipiggg
博客等级 码龄21年 1粉丝 15原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值