【刷题之路Ⅱ】LeetCode 274275. H指数ⅠⅡ

news2024/11/20 18:44:26

【刷题之路Ⅱ】LeetCode 274&275. H指数Ⅰ&Ⅱ

  • 一、题目描述
  • 二、解题
    • 1、方法1——排序
      • 1.1、思路分析
      • 1.2、代码实现
      • 1.3、升级到275题的二分法
        • 1.3.1、思路分析
          • 1.3.2、代码实现
    • 2、方法2——计数排序
      • 2.1、思路分析
      • 2.2、代码实现

一、题目描述

原题连接: 274. H 指数&275. H 指数 II
题目描述:
给你一个整数数组 citations ,其中 citations[i] 表示研究者的第 i 篇论文被引用的次数。计算并返回该研究者的 h 指数。

根据维基百科上 h 指数的定义:h 代表“高引用次数”,一名科研人员的 h指数是指他(她)的 (n 篇论文中)总共有 h 篇论文分别被引用了至少 h 次。且其余的 n - h 篇论文每篇被引用次数 不超过 h 次。
如果 h 有多种可能的值,h 指数 是其中最大的那个。

示例 1:

输入: citations = [3,0,6,1,5]
**输出:**3
解释:给定数组表示研究者总共有 5 篇论文,每篇论文相应的被引用了 3, 0, 6, 1, 5 次。
由于研究者有 3 篇论文每篇 至少 被引用了 3 次,其余两篇论文每篇被引用 不多于 3 次,所以她的 h 指数是 3。

示例 2:

输入: citations = [1,3,1]
输出: 1

提示:
n == citations.length
1 <= n <= 5000
0 <= citations[i] <= 1000

而275题只是在原有的基础上将数组进行升序排序了

二、解题

1、方法1——排序

1.1、思路分析

很明显h是不会超过数组元素个数的,而如果我们将数组进行降序排序之后发现数组的最后一个元素都大于等于数组的元素个数,那么h就为数组长度了:
在这里插入图片描述
所以我们可以先将数组进行降序排序,然后将h初始化为0,然后遍历数组,如果citations[i]大于h,那就让h++,而一旦我们发现citations<=h,那就说明citations后面的元素都是小等于h的数字了,这时候我们也就没有在遍历下去的必要了,直接跳出循环即可,例如:
在这里插入图片描述
最后返回h即可。
同样的,这一解法对于275题也是有效的。

1.2、代码实现

有了以上思路,那我们写起代码来也就水到渠成了:

// 先写一个函数,反向比较两个整数的大小
int cmp_int(const void *p1, const void *p2) {
    assert(p1 && p2);
    return *((int*)p2) - *((int*)p1);
}
int hIndex(int* citations, int citationsSize){
    assert(citations);
    // 先对数组进行排序
    qsort(citations, citationsSize, sizeof(int), cmp_int);
    int h = 0;
    int i = 0;
    for (i = 0; i < citationsSize; i++) {
        if (citations[i] > h) {
            h++;
        } else {
            break;
        }
    }
    return h;
}

时间复杂度:O(nlogn),为数组的长度,时间复杂度主要取决于排序数组的复杂度。
空间复杂度:O(1),我们只需要用到常数级的额外空间。

1.3、升级到275题的二分法

1.3.1、思路分析

既然275题已经帮我们把数组升序排序好了,那我们就可以考虑使用二分法。
通过上一解法我们可以看出,如果在遍历到citations[i]之前h是一直增加的,那么当遍历到citations[i]时,h的值其实就等于其下标i:
在这里插入图片描述
所以在上一解法中我们其实只需要找到第一个citations[i] <= i的元素即可。
而将这个思路延伸到以升序排序的数组中,其实我们只需要找到第一个大于等于包括它在内的后面的元素个数的元素citations[i]即可,例如:
在这里插入图片描述
这里的元素3是第一个大于等于后面元素个数的元素,所以我们直接返回这个个数即可。
而这个找元素的操作,我们用二分法完成。

1.3.2、代码实现

有了以上思路,那我们写起代码来也就水到渠成了:

int hIndex(int* citations, int citationsSize){
    assert(citations);
    int left = 0;
    int mid = 0;
    int right = citationsSize - 1;
    while (left <= right) {
        if (citations[left] >= citationsSize - left) {
            return citationsSize - left;
        }
        mid = left + (right - left) / 2;
        if (citations[mid] < citationsSize - mid) {
            left = mid + 1;
        } else {
        	// 其他情况我们都让right往左移
            right = mid;
        }
    }
    return 0;
}

时间复杂度:O(longn),n位数组的长度。
空间复杂度:O(1),我们只需要用到常数级的额外空间。

2、方法2——计数排序

对于274题,我们其实还可以用计数排序的思路来解题。

2.1、思路分析

因为h不可能大于数组的长度n,所以对于引用次数大于等于n的论文,我们就可以把他算进至少被引用了n次的论文。
所以我们可以额外创建一个长度为n+1的数组counter,其中counter[i]表示被引用了i次的论文的数量。
当我们创建好了数组统计好了数组counter之后,我们就可以逆序遍历数组counter,先将h初始化为0,然后每遍历到一个元素counter[i]就让好加上counter[i]。
因为题目要求我们找到最大的h,所以当我们找到第一个h >= i的元素时就可以直接返回h。
同样的,这个思路对于275题也是适用的。

2.2、代码实现

有了以上思路,那我们写起代码来也就水到渠成了:

int hIndex(int* citations, int citationsSize){
    assert(citations);
    int n = citationsSize;
    // 先创建一个计数数组
    int *counter = (int*)malloc((n + 1) * sizeof(int));
    if (NULL == counter) {
        perror("malloc fail");
        return -1;
    }
    // 对counter进行初始化
    int i = 0;
    for (i = 0; i <= n;i++) {
        counter[i] = 0;
    }
    // 初始化counter数组
    for (i = 0; i < n; i++) {
        if (citations[i] >= n) {
            counter[n]++;
        } else {
            counter[citations[i]]++;
        }
    }
    // 找到h
    int h = 0;
    for (i = n; i >= 0; i--) {
        h += counter[i];
        if (h >= i) {
            return i;
        }
    }
    return 0;
}

时间复杂度:O(n),n为数组的长度。
空间复杂度:O(n),我们需要额外用到n+1个空间,所以空间复杂度为O(n)。

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

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

相关文章

C语言专升本编程题复习

1.求100以内的素数 int main( ) { int i,j,count0;for(i1;i<100;i){for(j2;j<i;j){if(i%j0)break;}if(ij){count; printf("%d ",i);if(count%50)printf("\n");}} }2.求1000以内的完数 * 完数&#xff1a;等于其因子&#xff08;不含本身&…

【五一创作】SAP入门到放弃系列之批次确定配置

概念&#xff1a; 在后勤涉及物料移动或消耗流程中&#xff0c;从采购到生产到销售&#xff0c;涉及启用批次的物料&#xff0c;需要一次又一次地为出入库业务中的库存指定批次。如果企业的出库库批次管理有一定的管理要求&#xff0c;比如先进先出&#xff0c;就可以针对货物…

基于Java语言开发B/S架构实现的云HIS

一、云HIS系统框架简介 1、技术框架 &#xff08;1&#xff09;总体框架&#xff1a; SaaS应用&#xff0c;全浏览器访问 前后端分离&#xff0c;多服务协同 服务可拆分&#xff0c;功能易扩展 &#xff08;2&#xff09;技术细节&#xff1a; 前端&#xff1a;AngularNg…

级数可视化

泰勒级数 数学家们普遍偏爱多项式&#xff0c;如果评选一下高等数学里面最重要的公式&#xff0c;泰勒公式一定榜上有名&#xff0c;泰勒公式的核心思想就是把一个给定的任意函数&#xff0c;展开成多项式的形式&#xff0c;如果是有限项&#xff0c;就像作泰勒多项式&#xf…

深入了解云计算:发展历程、服务模型、未来趋势

开篇博主 bluetata 的观点&#xff1a;PaaS 服务必将是未来10年云计算权重最高的趋势&#xff08;05/02/2023 15:32&#xff09; 文章目录 一、前言二、认识了解云计算2.1 什么是云计算2.1.1 维基百科上的云计算定义2.1.2 NIST 标准云计算定义2.1.3 如果被面试如何解释云计算 2…

MYSQL-数据库管理(下)

查看数据库信息 show database 查看数据库中的表信息 use 数据库名 #切换到书库中 show tables show tables in mysql 显示数据表的结构&#xff08;字段&#xff09; describe user; Field:字段名称 type:数据类型 Null :是否允许为空 Key :主键 Type:数据类型 Null :是否…

武忠祥老师每日一题||不定积分基础训练(五)

∫ x f ′ ( x ) d x \int xf{}(x)\,{\rm d}x ∫xf′(x)dx ∫ x d f ( x ) \int x\,{\rm d}{f(x)} ∫xdf(x) x f ( x ) − ∫ f ( x ) d x xf(x)-\int f(x)\,{\rm d}x xf(x)−∫f(x)dx 由题知&#xff1a; f ( x ) ( ln ⁡ 2 x ) ′ 2 ln ⁡ x 1 x 2 ln ⁡ x x f(x)({…

宋爽:利用大数据解码遗传学的秘密 | 提升之路系列(七)

导读 为了发挥清华大学多学科优势&#xff0c;搭建跨学科交叉融合平台&#xff0c;创新跨学科交叉培养模式&#xff0c;培养具有大数据思维和应用创新的“π”型人才&#xff0c;由清华大学研究生院、清华大学大数据研究中心及相关院系共同设计组织的“清华大学大数据能力提升项…

【Git】Gitee免密push(TencentCloudLinux)

前提&#xff1a; 我用的是腾讯云的Centos(Linux)服务器 我创建好了仓库 我配置过git 可以正常用密码push 以上自行解决 我们直接配置公钥解决免密push 1.在服务器上创建公钥 在用户根目录创建 公钥 邮箱写自己的 随意写 我写的是gitee绑定的邮箱 ssh-keygen -t ed25519 -C…

第四期 微信云开发之订阅消息以及定时发送(触发器)

前言 在我们开发过程中&#xff0c;很多场景都会使用到微信小程序订阅消息功能&#xff0c;例如打卡通知、订餐通知等等。但是在云开发过程中&#xff0c;没有后台的情况下&#xff0c;如何进行消息的定时通知呢&#xff1f;下面我将从小程序订阅消息到定时发送订阅消息进行一个…

改进YOLOv5:结合位置编码CoordConv,提升行人目标等预测能力 | 卷积加上坐标,从而使其具备了空间感知能力

CoordConv:给卷积加上坐标,从而使其具备了空间感知能力 核心代码CoordConv代码common代码:yolo注册yaml文件:测试众所周知,深度学习里的卷积运算是具有平移等变性的,这样可以在图像的不同位置共享统一的卷积核参数,但是这样卷积学习过程中是不能感知当前特征在图像中的坐标…

STM-32:SPI通信外设

目录 一、前言二、SPI功能框图三、SPI通信读写数据 一、前言 STM32的SPI外设可用作通讯的主机及从机&#xff0c;支持最高的SCK时钟频率为fpclk/2 (STM32F103型号的芯片默认 fpclk1为 36MHz&#xff0c;fpclk2为 72MHz)&#xff0c;完全支持 SPI协议的4种模式&#xff0c;数据…

RestTemplate 请求第三方网站数据 定时插入到数据库

目录 0 课程视频 1 RestTemplate-> 是Web Http 客户端请求 模板工具 1.1 使用RestTemplate -> 选择执行引擎 Http客户端请求工具 1.2 执行引擎 Http客户端请求工具 1.2.1 JDK HttpUrlConnection 1.2.2 Apache HttpClient 1.2.3 OkHttp 1.2 升级版 -> WebClien…

Android 12.0 Launcher3仿ios长按app图标实现抖动动画开始拖拽停止动画

1.概述 在12.0的系统rom定制化开发中,在对系统原生Launcher3的定制需求中,也有好多功能定制的,在ios等电子产品中 的一些好用的功能,也是可以被拿来借用的,所以在最近的产品开发需求中,需求要求模仿ios的 功能实现长按app图标实现抖动动画,接下来看如何分析该功能的实现…

Centos7快速安装Logstash 7.17.7并实现MySQL中数据导入Elasticsearch

可以通过以下命令在线安装 Logstash 7.17.7 sudo rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch sudo rpm -ivh https://artifacts.elastic.co/downloads/logstash/logstash-7.17.7-x86_64.rpm安装完成后&#xff0c;需要添加环境变量 export PATH$PATH:…

ARM处理器的指令集(3)

ARM处理器的指令集 一、数据处理类指令 数据处理指令只能对寄存器的内容进行操作&#xff0c;而不能对内存中的数据进行操作&#xff0c;所以ARM数据处理指令均可以选择使用S后缀&#xff0c;以影响状态标志位。 影响状态标志位的命令&#xff1a; MOVS–>数据传送指令&am…

java servlet 农机租赁网站系统Myeclipse开发mysql数据库web结构jsp编程计算机网页项目

一、源码特点 java servlet 农机租赁网站系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助 系统采用 serlvetdaobean 模式开发 &#xff0c;系统具有完整的源代码和数 据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,M…

[架构之路-179]-《软考-系统分析师》-19- 系统可靠性分析与设计 -1- 故障模型、可靠性模型、可靠性分析

目录 前言&#xff1a; 1 9 . 1 系统可靠性概述 19.1.1 系统故障模型 1. 在信息系统中&#xff0c;故障或错误有如下儿种表现形式&#xff1a; 2. 故障的缘由 3. 故障模型 &#xff08;1&#xff09;逻辑电路级的故障 &#xff08;2&#xff09; 数据结构级的故障 &a…

【大数据Hadoop】HDFS3.3.1-Datanode-DataStorage的实现原理

DataStorage的实现原理 前言Storage类继承关系StorageInfoStorage.StorageStateStorage.StorageDirectory文件夹操作加锁/解锁操作存储状态恢复操作 StorageDataStorage 前言 Datanode 最重要的功能就是管理磁盘上存储的 HDFS 数据块。Datanode 将这个管理功能切分为两个部分&…

确定不进来看看吗?详细讲解C语言文件操作(示例分析每个函数)

前言 &#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;推荐专栏: &#x1f354;&#x1f35f;&#x1f32f; c语言初阶 &#x1f511;个人信条: &#x1f335;知行合一 &#x1f349;本篇简介:>:讲解c语言中的文件操作,文件的读取,输入输出,流的概念…