Leetcode 剑指 Offer II 071.按权重随机选择

题目难度: 中等

原题链接

今天继续更新 Leetcode 的剑指 Offer(专项突击版)系列, 大家在公众号 算法精选 里回复 剑指offer2 就能看到该系列当前连载的所有文章了, 记得关注哦~

题目描述

给定一个正整数数组 w ,其中 w[i] 代表下标 i 的权重(下标从 0 开始),请写一个函数 pickIndex ,它可以随机地获取下标 i,选取下标 i 的概率与 w[i] 成正比。

例如,对于 w = [1, 3],挑选下标 0 的概率为 1 / (1 + 3) = 0.25 (即,25%),而选取下标 1 的概率为 3 / (1 + 3) = 0.75(即,75%)。

也就是说,选取下标 i 的概率为 w[i] / sum(w) 。

示例 1:

  • 输入:
    • inputs = [“Solution”,“pickIndex”]
    • inputs = [[[1]],[]]
  • 输出:
    • [null,0]
  • 解释:
    • Solution solution = new Solution([1]);
    • solution.pickIndex(); // 返回 0,因为数组中只有一个元素,所以唯一的选择是返回下标 0。

示例 2:

  • 输入:
    • inputs = [“Solution”,“pickIndex”,“pickIndex”,“pickIndex”,“pickIndex”,“pickIndex”]
    • inputs = [[[1,3]],[],[],[],[],[]]
  • 输出:
    • [null,1,1,1,1,0]
  • 解释:
    • Solution solution = new Solution([1, 3]);
    • solution.pickIndex(); // 返回 1,返回下标 1,返回该下标概率为 3/4 。
    • solution.pickIndex(); // 返回 1
    • solution.pickIndex(); // 返回 1
    • solution.pickIndex(); // 返回 1
    • solution.pickIndex(); // 返回 0,返回下标 0,返回该下标概率为 1/4 。
    • 由于这是一个随机问题,允许多个答案,因此下列输出都可以被认为是正确的:
    • [null,1,1,1,1,0]
    • [null,1,1,1,1,1]
    • [null,1,1,1,0,0]
    • [null,1,1,1,0,1]
    • [null,1,0,1,0,0]
    • 诸若此类。

提示:

  • 1 <= w.length <= 10000
  • 1 <= w[i] <= 10^5
  • pickIndex 将被调用不超过 10000 次

题目思考

  1. 如何设计随机算法?
  2. 如何优化时间复杂度?

解决方案

思路
  • 分析题目, 要考虑每个下标的权重, 我们显然不能直接随机取[0,n)的下标, 这样会导致每个下标取到的概率相同, 如何解决呢?
  • 根据题目例子, 我们可以发现, 每个下标的取值概率等于其权重除以权重总和
  • 利用这一点, 假设权重总和是 total, 我们随机取[0,total)之间的某个数字, 然后判断它落在了哪个下标的范围内, 这样就把下标权重考虑在内了
  • 举个例子, 假设数组 w 是[3,2,4], 那么总权重和就是3+2+4=9
  • 下标 0 的权重是 3, 它负责的范围是[0,2]
  • 下标 1 的权重是 2, 它负责的范围是[3,4]
  • 下标 2 的权重是 4, 它负责的范围是[5,8]
  • 我们随机取[0,9)之间的某个数字, 它落在哪个下标范围就返回哪个下标, 这样就保证了每个下标的取值概率等于其权重除以权重总和
  • 有了思路后, 如何写出代码呢?
  • 不难发现每个下标的负责范围的起点就是其前缀和, 即[0,3,5,9], 注意最后的 9 代表了总和, 不属于某个下标起点
  • 所以我们可以在初始化时求出原始数组对应的前缀和数组 sms, 最后一个元素sms[-1]就是总和
  • 然后 pickIndex 时随机取[0,sms[-1])之间的数字 x, 并从头开始遍历前缀和数组, 找到第一个满足sms[i]<=x<sms[i+1]的下标 i, 即为考虑权重后随机选取的下标
  • 不过上述查找过程需要线性遍历, 时间复杂度是 O(N), 能否继续优化呢?
  • 注意到题目给出的是正整数数组, 所以前缀和是单调递增的, 我们可以利用二分查找来优化
  • 这里我们能够完美利用 Python 提供的右二分 bisect_right, 它的语义是:
    • 如果数字存在于查找数组, 返回对应下标加 1
    • 如果数字不存在, 则返回首个大于该数字的下标或数组长度(如果已有数字都不大于查找数字时)
  • 这样右二分查找到的下标正是所需下标的下一个下标, 同样拿上面例子举例:
    • 假如查找数字是 0, 则右二分返回下标 1, 所需下标是 0
    • 假如查找数字是 1, 则右二分返回下标 1, 所需下标是 0
    • 假如查找数字是 2, 则右二分返回下标 1, 所需下标是 0
    • 假如查找数字是 3, 则右二分返回下标 2, 所需下标是 1
    • 假如查找数字是 4, 则右二分返回下标 2, 所需下标是 1
  • 大家如果感兴趣的话也可以自己尝试实现这个二分查找的过程, 基本类似前面的题目Leetcode 剑指 Offer II 068.搜索插入位置, 只需要稍作改动, target 存在时返回对应下标加 1, 而不是下标本身
  • 下面代码中有详细的注释, 方便大家理解
复杂度
  • 时间复杂度 O(logN): 每次 pickIndex 使用二分查找, 时间复杂度是 O(logN)
  • 空间复杂度 O(N): 需要额外存储前缀和数组
代码
class Solution:def __init__(self, w: List[int]):# 前缀和+二分查找self.sms = [0]for x in w:# 统计前缀和数组self.sms.append(x + self.sms[-1])def pickIndex(self) -> int:# 随机选择[0,数字总和)之间的一个数字xx = random.randrange(0, self.sms[-1])# 二分查找当前数字落在了哪个下标的范围内# 这里使用右二分bisect_right, 且二分得到的下标要减1return bisect.bisect_right(self.sms, x) - 1

大家可以在下面这些地方找到我~😊

我的 GitHub

我的 Leetcode

我的 CSDN

我的知乎专栏

我的头条号

我的牛客网博客

我的公众号: 算法精选, 欢迎大家扫码关注~😊

算法精选 - 微信扫一扫关注我

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/781338.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

电子级高纯PFA材质实验室器皿耗材PFA漏斗PFA试剂瓶PFA烧杯

PFA三角漏斗&#xff0c;整体均是PFA材质&#xff0c;无污染风险&#xff0c;可高压灭菌。 尺寸&#xff1a;外径40mm、160mm PFA三角漏斗 特点&#xff1a; 1、一体式成型&#xff0c;结构稳定&#xff1b; 2、化学耐受性强&#xff0c;耐受强酸、强碱以及各种有机溶剂&…

如何划分训练集、测试集、验证集

训练集、测试集和验证集是在机器学习和数据科学中常用的术语&#xff0c;用于评估和验证模型的性能。它们通常用于监督学习任务中。 1. 训练集&#xff08;Training Set&#xff09;&#xff1a;训练集是用于训练机器学习模型的数据集。在训练期间&#xff0c;模型使用训练集中…

FPGA----ZCU106的petalinux 2019.1使用USB传输数据

1、实际项目中需要用到开发板的串口进行数据交互&#xff0c;之前讲的几节只是启动了网口&#xff08;如下链接&#xff09;。因此&#xff0c;本次给大家带来的官方自带串口例程的使用方法&#xff0c;本文的vivado工程和下述连接一样&#xff0c;PL端什么配置都没有。 FPGA-…

PostgreSQL到Doris的迁移技巧:实时数据同步新选择!

PostgreSQL可以说是目前比较抢手的关系型数据库了&#xff0c;除了兼具多样功能和强大性能之外&#xff0c;还具备非常优秀的可扩展性&#xff0c;更重要的是它还开源&#xff0c;能火不是没有理由的。 虽然PostgreSQL很强大&#xff0c;但是它也有短板&#xff0c;相对于专业…

淘宝商品详情数据(商品分析,竞品分析,代购商城建站与跨境电商,ERP系统商品数据选品)

淘宝商品详情数据在多个业务场景中发挥着关键作用&#xff0c;以下是一些主要的应用场景&#xff1a; 请求示例&#xff0c;API接口接入Anzexi58 商品分析&#xff1a;通过对淘宝商品详情的全面分析&#xff0c;商家可以深入了解商品的属性、价格、销售量、评价等信息。这些数…

ATFX汇市:欧元区的2月M1增速为-7.7%,潜在通胀下修,欧元币值受冲击

ATFX汇市&#xff1a;衡量经济体的潜在通胀指标&#xff0c;除了CPI数据、失业率数据外&#xff0c;还有M1、M3数据。昨日&#xff0c;欧洲央行公布了2月份欧元区货币发展报告&#xff0c;其中提到&#xff1a;广义货币总量M3的年增长率从1月份的0.1%上升到2024年2月的0.4%&…

机器学习--支持向量机(通俗版本+demo)

场景 假设我们要在一个在线零售平台上自动区分商品评论是正面的还是负面的。评论中的语言多种多样&#xff0c;且往往含有大量的非结构化文本数据&#xff0c;直接使用简单的规则来分类是非常困难。这时候我们采取支持向量机算法来分类是一个比较好的选择。 支持向量机 支持…

RPA-财务对账邮件应用自动化(客户对账机器人)

《财务对账邮件应用自动化》&#xff0c;将会使用邮箱的SMTP服务&#xff0c;小北把资源包绑定在这篇博客了 Uibot (RPA设计软件)———机器人的小项目友友们可以参考小北的课前材料五博客~ (本博客中会有部分课程ppt截屏,如有侵权请及请及时与小北我取得联系~&#xff09; …

MATLAB 自定义生成直线点云(详细介绍) (47)

MATLAB 自定义生成直线点云 (详细介绍)(47) 一、算法介绍二、具体步骤二、算法实现1.代码2.效果一、算法介绍 通过这里的直线生成方法,可以生成模拟直线的点云数据,并通过调整起点、终点、数量和噪声水平等参数来探索不同类型的直线数据。这种方法可以用于测试、验证和开…

【涨薪技术】0到1学会性能测试 —— LR录制回放事务检查点

上一次推文我们分享了性能测试分类和应用领域&#xff0c;今天带大家学习性能测试工作原理、事务、检查点&#xff01;后续文章都会系统分享干货&#xff0c;带大家从0到1学会性能测试&#xff0c;另外还有教程等同步资料&#xff0c;文末免费获取~ 01、LR工作原理 ​通常我们…

gitee拉取与推送

&#x1f331;博客主页&#xff1a;青竹雾色间 &#x1f618;博客制作不易欢迎各位&#x1f44d;点赞⭐收藏➕关注 目录 一&#xff0c;从本地推送项目到gitee1.首先我们在gitee上创建一个仓库2.clone远程仓库到本地3.git的三板斧3.1. add - 将代码添加到本地仓库3.2. commit …

HarmonyOS实战开发-实现Ability内页面间的跳转和数据传递。

介绍 本篇Codelab基于Stage模型下的Ability开发&#xff0c;实现Ability内页面间的跳转和数据传递。 最终效果图如下&#xff1a; 相关概念 页面路由&#xff1a;提供通过不同的url访问不同的页面&#xff0c;包括跳转到应用内的指定页面、用应用内的某个页面替换当前页面、…

UWB辅助RTK如何应对极端环境

1.UWB定位 - UWB&#xff08;Ultra-Wideband&#xff09;是一种无线通信技术&#xff0c;其特点是具有较宽的频带&#xff0c;可以提供0.1-0.5m高精度的距离测量。 - UWB定位需要四台基站&#xff08;每台基站视距间隔50-100米&#xff09;呈矩形安装部署&#xff0c;以实现…

JHY-31复合电压继电器 额定电压Un=110VDC 板后接线 JOSEF约瑟

用途&#xff1a; JHY-31复合电压继电器使用于电力系统的继电保护线路中&#xff0c;作为各种类型故障的判别元件和电压闭锁元件。 继电器型号名称&#xff1a; 例:辅助直流工作电压为110V的复合电压继电器的订货代号为: JHY-31/110V。 工作原理&#xff1a; 继电器内部具有负…

9、jenkins微服务持续集成(一)

文章目录 一、流程说明二、源码概述三、本地部署3.1 SpringCloud微服务部署本地运行微服务本地部署微服务3.2 静态Web前端部署四、Docker快速入门一、流程说明 Jenkins+Docker+SpringCloud持续集成流程说明 大致流程说明: 开发人员每天把代码提交到Gitlab代码仓库Jenkins从G…

基于GA遗传优化的离散交通网络双层规划模型设计matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于GA遗传优化的离散交通网络双层规划模型设计.优化输出路段1和路段2的收费情况收敛过程。 2.测试软件版本以及运行结果展示 MATLAB2022a版本运行 3.核心程序…

Web前端—(原生JS)歌词滚动效果

歌词滚动效果实现 歌词滚动效果HTML部分CSS部分JS部分解析歌词字符串&#xff0c;得到歌词的对象数组计算在当前情况下&#xff0c;播放器播放到第几秒的情况创建歌词元素设置ul元素的偏移量最后对时间变化的事件进行监听完整JS代码 歌词滚动效果 实现效果如图所示&#xff1a…

可重复不限数量结构数列的演化

有一个6*6的平面&#xff0c;这个平面的行和列可以自由的变换&#xff0c;在这个平面上有一个4点结构数列 按照8&#xff0c;13&#xff0c;5&#xff0c;8的顺序排列。让这个数列按照4-5-4的方式演化 这个数列很快收敛,收敛顺序为13&#xff0c;8&#xff0c;8&#xff0c;5 8…

前端小白如何理解mvc mvp mvvm

架构、框架、设计模式是都是啥&#xff1f; 架构&#xff1a;抽象出来不同组织或者对象亦或是简单组件&#xff0c;根据需求和各个单元的功能&#xff0c;进行组合排列。 从而完成系统的运行或者是实现目标。 框架&#xff1a;使用什么样的规则&#xff0c;什么样的开发语言&…

接口自动化测试问题汇总

本篇文章分享几个接口自动化用例编写过程遇到的问题总结&#xff0c;希望能对初次探索接口自动化测试的小伙伴们解决问题上提供一小部分思路。 sql语句内容出现错误 空格&#xff1a;由于有些字段判断是变量&#xff0c;需要将sql拼接起来&#xff0c;但是在拼接字符串时没有…