力扣面试经典150 —— 11-15题

  • 力扣面试经典150题
  • 在 VScode 中安装 LeetCode 插件即可使用 VScode 刷题,安装 Debug LeetCode 插件可以免费 debug
  • 本文使用 python 语言解题,文中 “数组” 通常指 python 列表;文中 “指针” 通常指 python 列表索引

文章目录

  • 11. [中等] H指数
    • 11.1 解法1:暴力法
    • 11.2 解法2:计数排序
    • 11.3 解法3:排序
  • 12. [中等] O(1) 时间插入、删除和获取随机元素
    • 12.1 解法1:哈希表+变长数组
  • 13. [中等] 除自身以外的数组的乘积
    • 13.1 解法1:左右乘积列表
    • 13.2 解法2:左右乘积列表
  • 14. [中等] 加油站
    • 14.1 解法1:一次遍历
  • 15. [困难] 分发糖果
    • 15.1 解法1:两次遍历

11. [中等] H指数

  • 题目链接
  • 标签:数组、计数排序、排序
    在这里插入图片描述

11.1 解法1:暴力法

  • 根据题目可知,h 指数不能超过论文发表总数,也不能超过最高引用此次,其最大值为 min(max(citations), len(citations))。从该最大可能取值开始反向遍历所有可能取值 i,统计引用次数 >=i 的论文数量 paper_cnt,直到找到满足 h 指数的定义(即 paper_cnt>=i)的取值为止。这是一种带剪枝的暴力搜索方法
    class Solution:def hIndex(self, citations: List[int]) -> int:# 根据定义,h 指数的理论最大值max_h = min(max(citations), len(citations))# 从 max_h 开始反向遍历考察所有 h 指数的可能取值 i for i in range(max_h, -1, -1):# 统计引用次数 >= i 的论文数量paper_cnt = 0for cite in citations:if cite >= i:paper_cnt += 1# 满足 h 指数定义则返回if paper_cnt >= i:return ireturn 0
    
  • 时间复杂度 O ( n 2 ) O(n^2) O(n2),空间复杂度 O ( 1 ) O(1) O(1)

11.2 解法2:计数排序

  • 以上暴力法中,对于每一个候选的 h 指数取值都做了一次遍历计数,因此时间复杂度高。一种优化方式是,先用过一次遍历完成所有计数操作,再通过另一次和暴力法相同的反向遍历确定 h 指数的值。具体而言,第一次遍历中我们用 defaultdict 统计引用量为 h 指数各可能取值i 的论文数量,之后在反向遍历时通过求和得到引用量 >=i 的论文数量
  • 这种方法通过引入 O ( n ) O(n) O(n) 的额外存储空间,将时间复杂度从 O ( n 2 ) O(n^2) O(n2) 降低到 O ( n ) O(n) O(n)
    class Solution:    def hIndex(self, citations: List[int]) -> int:# 根据定义,h 指数的理论最大值max_h = min(max(citations), len(citations))# 用 counter 统计引用量 >= 不同 cite 值的论文数量from collections import defaultdictcounter = defaultdict(int)for cite in citations:cite = max_h if cite > max_h else citecounter[cite] += 1# 从 max_h 开始反向遍历考察所有 h 指数的可能取值 i tot = 0     for i in range(max_h, -1, -1):tot += counter[i]   # 引用量不少于 i 次的论文总数if tot >= i:        # 满足 h 指数定义则返回return ireturn 0
    
  • 时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( n ) O(n) O(n)

11.3 解法3:排序

  • 先初始化 h=0,然后把引用次数 citations 排序并大到小遍历。如果当前 h 指数为 h 并且在遍历过程中找到当前值 citations[i]>h,则说明我们找到了一篇被引用了至少 h+1 次的论文,所以 h+=1。继续遍历直到 h 无法继续增大后返回即可
    class Solution:def hIndex(self, citations: List[int]) -> int:sorted_citation = sorted(citations, reverse = True)h = 0; i = 0; n = len(citations)while i < n and sorted_citation[i] > h:h += 1i += 1return h
    
  • 时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn),空间复杂度 O ( l o g n ) O(logn) O(logn)(这两个都是排序算法的复杂度)

12. [中等] O(1) 时间插入、删除和获取随机元素

  • 题目链接
  • 标签:设计、数组、哈希表、数学
    在这里插入图片描述

12.1 解法1:哈希表+变长数组

  • 要求实现插入删除获取随机元素操作的平均时间复杂度为 O ( 1 ) O(1) O(1)
    1. 变长数组:可以在 O ( 1 ) O(1) O(1) 的时间内完成获取随机元素操作。但是由于需要 O ( n ) O(n) O(n) 时间判断元素是否存在,因此无法满足插入和删除的时间复杂度要求
    2. 哈希表:哈希表的核心思想,是通过函数函数把元素映射到存储位置索引,这样就能在 O ( 1 ) O(1) O(1) 的时间内判断元素是否存在,或找到元素存储位置进行插入或删除。但哈希表无法在 O ( 1 ) O(1) O(1) 时间内获取当前全体元素,因此无法满足随机取元素的时间复杂度要求
  • 通过结合变长数组和哈希表,可以实现题目要求
    class RandomizedSet:def __init__(self):from collections import defaultdictimport randomself.item = []  # 在此存储元素self.idx = {}   # 哈希表,将元素映射到其在 self.item 中的索引位置def insert(self, val: int) -> bool:if val in self.idx:return Falseself.item.append(val)self.idx[val] = len(self.item) - 1return Truedef remove(self, val: int) -> bool:if not val in self.idx:return Falseidx_val = self.idx[val]         item_last = self.item[-1]       self.item[idx_val] = item_last  # self.item 中,用 item_last 替换目标元素self.idx[item_last] = idx_val   # self.idx 哈希表中,更新 item_last 对应的索引位置self.item.pop()                 # 弹出已经移动到 idx_val 处的 item_lastdel self.idx[val]               # 删除目标元素在哈希表中的索引return Truedef getRandom(self) -> int:return random.choice(self.item)# Your RandomizedSet object will be instantiated and called as such:
    # obj = RandomizedSet()
    # param_1 = obj.insert(val)
    # param_2 = obj.remove(val)
    # param_3 = obj.getRandom()
    # @lc code=end
    

13. [中等] 除自身以外的数组的乘积

  • 题目链接
  • 标签:数组、前缀和
    在这里插入图片描述

13.1 解法1:左右乘积列表

  • 用双指针同时从左右开始遍历列表,将左侧所有数字的乘积(前缀积)和右侧所有数字的乘积(后缀积)存储到两个辅助列表中。最后将两个辅助列表对应位置相乘得到结果
    class Solution:def productExceptSelf(self, nums: List[int]) -> List[int]:# pre_prods 存储每个索引位置所有前驱元素乘积# post_prods 存储每个索引位置所有后继元素乘积pre_prod, post_prod = 1, 1pre_prods, post_prods = [], []left, right = 0, -1for i in range(len(nums)):pre_prods.append(pre_prod)post_prods.append(post_prod)pre_prod *= nums[left]post_prod *= nums[right]left += 1right -= 1post_prods.reverse() # 输出中每个索引位置,取 pre_prods 和 post_prods 对应位置元素相乘即可res = []for i in range(len(nums)):res.append(pre_prods[i] * post_prods[i])return res
    
  • 时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( n ) O(n) O(n)

13.2 解法2:左右乘积列表

  • 以上方法需要构造存储前缀积和后缀积的两个辅助列表。为了减少空间复杂度,可以先构造前缀积列表,然后在计算后续元素乘积时直接将其乘到前缀积列表中并作为输出。这样可以把空间复杂度降低到 O ( 1 ) O(1) O(1)(不考虑输出数组)
    class Solution:def productExceptSelf(self, nums: List[int]) -> List[int]:# pre_prods 存储每个索引位置所有前驱元素乘积pre_prod = 1res = []for num in nums:res.append(pre_prod)pre_prod *= num# 再把后续元素乘积直接乘到 res 的对应位置上,实现 O(1) 的空间复杂度post_prod = 1for i in range(len(nums)-1, -1, -1):res[i] *= post_prodpost_prod *= nums[i]return res
    
  • 时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( 1 ) O(1) O(1)

14. [中等] 加油站

  • 题目链接
  • 标签:贪心、数组
    在这里插入图片描述

14.1 解法1:一次遍历

  • 最直接的思想是依次把每一个加油站作为起点进行考察,直到找到能够绕行一周的加油站为止,但是这种暴力解法时间复杂度高。可以通过减小被检查的加油站数目来降低时间复杂度。
  • 注意到这样一个事实:如果从 x 加油站出发最多只能到达 z 加油站,那么从 x 和 z 之间的 y 加油站出发一定无法到达超过 z 的位置。这是因为从 x 出发到达 y 时可能车里还有剩余燃油,直接从 y 出发不可能走得更远
  • 我们可以从第 0 个加油站开始判断能否环绕一周;如果不能,就从第一个无法到达的加油站开始继续检查。
    class Solution:def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:def _available_cnt(idx):# 计算从 idx 开始可以连续到达的加油站数量cnt, gas_left = 0, 0for i in range(n):gas_left += delta[(idx + i) % n] if gas_left < 0:return cntcnt += 1return cnt# 从各个加油站出发到下一个加油站导致的油量变化delta = [g - c for g, c in zip(gas, cost)]  # 检查从各个加油站出发能否环绕一周;不能则从第一个无法到达的加油站开始继续检查n, idx = len(gas), 0while idx < n:cnt = _available_cnt(idx)# 找到可能访问所有加油站的起点则返回if cnt == n:return idxidx += cnt + 1return -1
    
  • 时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( 1 ) O(1) O(1)

15. [困难] 分发糖果

  • 题目链接
  • 标签:贪心、数组
    在这里插入图片描述

15.1 解法1:两次遍历

  • “相邻的孩子中,评分高的孩子必须获得更多的糖果” 这一句话可以拆分成两个规则
    1. 左规则:ratings[i-1]<ratings[i] 时,i 号的糖果比 i-1 号多
    2. 右规则:ratings[i]>ratings[i+1] 时,i 号的糖果比 i+1 号多
  • 单独处理其中任意一个规则是简单的,以左规则为例,初始化分配糖果数为1,从左到右遍历,若分数递增则分配糖果数+1,反之重置为1。右规则同理。
    1. 对于仅满足左规则的分配数组 L,其在每一个分数递增段都从1开始递增,其余部分全是1
    2. 对于仅满足右规则的分配数组 R,其在每一个分数递减段都递减到1,其余部分全是1
  • 经过两次遍历得到 LR 后,直接给第 i i i 个小孩分配 max(L[i], R[i]) 颗糖果即可。为了分析这种操作的正确性,假设 L [ i ] > R [ i ] L[i] > R[i] L[i]>R[i],则 max ⁡ ( L [ i ] , R [ i ] ) = L [ i ] \max(L[i], R[i]) = L[i] max(L[i],R[i])=L[i],此时左规则一定满足,考虑右规则
    1. ratings[i]>ratings[i+1],此时分配数量 L [ i ] > R [ i ] > R [ i + 1 ] L[i]>R[i]>R[i+1] L[i]>R[i]>R[i+1] 一定满足右规则
    2. ratings[i-1]>ratings[i],这意味着 i i i 处于一个递减序列内,此时 L [ i ] = 1 L[i]=1 L[i]=1,不可能有 L [ i ] > R [ i ] L[i] > R[i] L[i]>R[i],故增加给第 i i i 个小孩的糖果数量不会导致在 i − 1 i-1 i1 处违反右规则
  • 综上,给出如下的求解代码
    class Solution:def candy(self, ratings: List[int]) -> int:n = len(ratings)# 仅考虑左规则对应的最少糖果分配left = [1, ]for i in range(n-1):left.append(left[i] + 1 if ratings[i+1] > ratings[i] else 1)# 仅考虑右规则对应的最少糖果分配ratings.reverse()right = [1, ]for i in range(n-1):right.append(right[i] + 1 if ratings[i+1] > ratings[i] else 1)right.reverse()# max 操作确定每个索引处同时满足左右规则的糖果数,求和return sum([max(l, r) for l, r in zip(left, right)])
    
  • 时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( n ) O(n) O(n)

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

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

相关文章

YOLOv9改进 添加三分支注意力机制TripletAttention

一、TripletAttention论文 论文地址: 2010.03045.pdf (arxiv.org) 二、TripletAttention结构 对于输入张量,TripletAttention通过旋转操作和残差变换建立维度间依赖关系,并以可忽略的计算开销对通道间和空间信息进行编码。TripletAttention通过几乎无参数的特点来建模通道…

qt如何配置ros环境

在Qt5.7的版本可以使用bash -i -c来启动qt&#xff0c;让Qt自己识别系统环境&#xff0c;不知道为什么Qt在之后的版本&#xff0c;这样使用都失效了。因为它会默认把CMAKE_PREFIX_PATH修改掉。 网上还有安装ros插件版本的qt creator&#xff0c;感觉失去了一些灵活性。 自己测试…

数据结构 第1章:绪论

文章目录 1. 绪论1.1. 数据结构 1.2. 算法1.2.1. 算法的基本概念1.2.2. 算法的时间复杂度1.2.3. 算法的空间复杂度 1. 绪论 程序 数据结构 算法 1.1. 数据结构 数据&#xff1a;是对客观事物的符号表示&#xff0c;在计算机科学中是指所有能输入到计算机中并被计算机程序处理…

Python: 如何绘制核密度散点图和箱线图?

01 数据样式 这是数据样式&#xff1a; 要求&#xff08;我就懒得再复述一遍了&#xff0c;直接贴图&#xff09;&#xff1a; Note&#xff1a;数据中存在无效值NA&#xff08;包括后续的DEM&#xff09;&#xff0c;需要注意 02 提取DEM 这里我就使用gdal去提取一下DEM列…

深度学习图像算法工程师--面试准备(2)

深度学习面试准备 深度学习图像算法工程师–面试准备&#xff08;1&#xff09; 深度学习图像算法工程师–面试准备&#xff08;2&#xff09; 文章目录 深度学习面试准备前言一、Batch Normalization(批归一化)1.1 具体步骤1.2 BN一般用在网络的哪个部分 二、Layer Normaliza…

CTP-API开发系列之八:报撤单代码实现

CTP-API开发系列之八&#xff1a;报撤单代码实现 CTP-API开发系列之八&#xff1a;报撤单代码实现前情回顾函数实现缓存FrontID 和 SessionID报单函数实现撤单函数实现 调用示例报单&#xff08;形成挂单&#xff09;对挂单进行撤单报单&#xff08;立即成交&#xff09;注意事…

XSS靶场-DOM型初级关卡

一、环境 XSS靶场 二、闯关 1、第一关 先看源码 使用DOM型&#xff0c;获取h2标签&#xff0c;使用innerHTML将内容插入到h2中 我们直接插入<script>标签试一下 明显插入到h2标签中了&#xff0c;为什么不显示呢&#xff1f;看一下官方文档 尽管插入进去了&#xff0…

系统运维网络知识汇总

一、系统运维中网络方面的规划与思考 系统运维建立在网络的基础之上&#xff0c;如果没有一个相对合理的网络架构&#xff0c;恐怕系统运维做起来也不是那么的顺手。一个公司基本上都会把网络和服务器独立开来&#xff0c;划分不同的区域摆放设备&#xff0c;很多时候都是物理…

基于Android的高校移动成绩查询系统的设计与实现

摘 要 在我国现今状态&#xff0c;互联网呈现出的高速发展状态以及高等教育的教学不断改革下&#xff0c;各高校的教务管理系统都已经从传统的纸质方式转向了基于Internet的绿色管理方式。而对于目前各高校所使用的都是浏览器/服务器&#xff08;B/S&#xff09;模式&#xff…

短视频解析接口分发系统,附带系统搭建教程

搭建教程 宝塔面板&#xff1a;Nginx系统 php7.2 Mysql 5.6-5.7 伪静态Thinkphp 上传文件直接访问域名安装即可 解析接口推荐&#xff1a;ce.qsy.mobi 源码免费下载地址抄笔记

JavaSE面试——类集框架List/Set/Queue

Collection 集成体系 Map 集成体系 List 和 Map、Set 的区别 1. 结构特点 1.存储数据类型&#xff1a; List 和 Set 是存储单列数据的集合&#xff0c;Map 是存储键和值这样双列数据的集合 2. 存储特点&#xff1a; List&#xff1a;存储数据有顺序&#xff0c;允许重复 …

kibana配置 dashbord,做可视化展示

一、环境介绍 这里我使用的kibana版本为7.17版本。 语言选择为中文。 需要已经有es&#xff0c;已经有kibana&#xff0c;并且都能正常访问。 二、背景介绍 kibana的可视化界面&#xff0c;可以配置很多监控统计界面。非常方便&#xff0c;做数据的可视化展示。 这篇文章&…

鸿蒙App基础

基础说明 .1、应用模型 .1.1、构成要素 应用组件 应用组件是应用的基本组成单位&#xff0c;是应用的运行入口。用户启动、使用和退出应用过程中&#xff0c;应用组件会在不同的状态间切换&#xff0c;这些状态称为应用组件的生命周期。应用组件提供生命周期的回调函数&…

Android 生成SO - 基础工程创建

最近需要给小伙伴扫盲一下如何使用Android Studio 生成一个SO文件&#xff0c;网上找了很多都没有合适的样例&#xff0c;那只能自己来写一个了。 原先生成SO是一个很麻烦的事情&#xff0c;现在Android Studio帮忙做了很多的事情&#xff0c;基本只要管好自己的C代码即可。 …

数据“隐领”未来!【隐私计算实训营】限时免费招募!

数智经济时代&#xff0c;为强化个人隐私信息保护&#xff0c;国家颁布了《国家安全法》、《网络安全法》、《数据安全法》等数据安全法律法规&#xff0c;并严厉处罚数据违规出海、侵权、滥用等问题。数据安全和隐私保护成为大家的共识。隐私计算技术在此背景下应运而生&#…

物联网云原生云边协同

文章目录 一、物联网平台设计1.物联网平台设计2.物联网平台实现 二、部署环境1.节点配置2.版本信息 三、物联网平台部署1.部署 Kubernetes 集群2.部署 KubeEdge3.部署 ThingsBoard 集群4.部署 ThingsBoard Edge4.1.创建 Edge 实例4.2.部署 PostgreSQL4.3.创建数据库4.4.部署 Th…

【C++】类与对象

文章目录 1. 面向过程与面向对象2. 类&#xff08;class&#xff09;类的作用域 3. 访问限定符封装 4. 类的实例化5. this指针6. 默认成员函数6.1 构造函数6.2 析构函数6.3 拷贝构造函数 1. 面向过程与面向对象 C语言是面向过程&#xff08;procedure-oriented&#xff09;的语…

“成像光谱遥感技术中的AI革命:ChatGPT应用指

遥感技术主要通过卫星和飞机从远处观察和测量我们的环境&#xff0c;是理解和监测地球物理、化学和生物系统的基石。ChatGPT是由OpenAI开发的最先进的语言模型&#xff0c;在理解和生成人类语言方面表现出了非凡的能力。本文重点介绍ChatGPT在遥感中的应用&#xff0c;人工智能…

数字脉搏:互联网的演进与社会脉络

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

React-路由小知识

1.默认路由 说明&#xff1a;当访问的是一级路由时&#xff0c;默认的二级路由组件可以得到渲染&#xff0c;只需要在二级路由的位置去掉path,设置index.属性为true。 2.404路由 说明&#xff1a;当浏览器输入ul的路径在整个路由配置中都找不到对应的pth,为了用户体验&#x…