当前位置: 首页 > news >正文

力扣(H指数)

一、题目分析

(一)问题描述

给定一个整数数组 citations,其中 citations[i] 表示研究者的第 i 篇论文被引用的次数。我们需要计算并返回该研究者的 H 指数。根据维基百科定义:H 指数代表“高引用次数”,一名科研人员的 H 指数是指他(她)至少发表了 h 篇论文,并且至少有 h 篇论文被引用次数大于等于 h 。如果有多个可能的 h 值,取最大的那个。

比如,若有论文引用次数数组为 [3,0,6,1,5],经过计算其 H 指数是 3,因为有 3 篇论文(引用次数为 3、6、5 )的引用次数大于等于 3 。

(二)核心目标

遍历处理论文引用次数数组,找到最大的 h 值,满足存在至少 h 篇论文的引用次数 ≥ h 。

二、算法思想:排序 + 线性遍历(贪心思想的体现)

(一)排序的作用

首先对 citations 数组进行排序(升序排序 )。排序之后,数组的顺序能够帮助我们更方便地找到符合 H 指数定义的那个 h 值。升序排序后,数组后面的元素值相对较大,我们可以从后往前或者从前往后,利用数组的有序性来判断满足条件的 h 。

(二)线性遍历与贪心策略

排序完成后,进行线性遍历。我们的贪心策略是:从数组的一端开始,寻找满足“存在 h 篇论文引用次数 ≥ h”这一条件的最大 h 。具体来说,对排序后的数组,我们从前往后遍历,对于索引 i ,考虑以 n - i 作为可能的 h 值(n 是数组长度,也就是论文的总篇数 ),判断当前论文的引用次数 citations[i] 是否大于等于 n - i 。一旦找到第一个满足该条件的 i ,那么 n - i 就是我们要找的最大 H 指数。这是因为数组是升序排列的,后面的元素值更大,当在某个位置满足条件后,继续往后遍历得到的 n - i 会更小,所以第一个满足条件的 n - i 就是最大的符合要求的 H 指数,这体现了贪心算法中“找到第一个满足局部条件就能得到全局最优”的思想 。

三、代码实现及详细注释

import java.util.Arrays;class Solution {public int hIndex(int[] citations) {// 第一步:对引用次数数组进行升序排序Arrays.sort(citations);int n = citations.length; // 获取论文的总篇数,也就是数组的长度for (int i = 0; i < n; i++) { // 对于当前索引i,考虑h值为n - i。这里的含义是:// 假设h是n - i,那么需要至少有n - i篇论文的引用次数≥h// 由于数组是升序排序的,citations[i]及后面的元素是较大的,当citations[i] >= n - i时,// 说明从i到n - 1位置的这n - i篇论文的引用次数都 >= citations[i](因为升序),也就 >= n - iif (citations[i] >= n - i) { return n - i; // 找到满足条件的最大h值,直接返回}}return 0; // 如果遍历完都没有满足条件的,说明H指数为0(比如所有论文引用次数都为0的情况 )}
}

(一)代码执行流程详解

  1. 排序操作
Arrays.sort(citations);

这行代码使用 Java 内置的 Arrays.sort 方法对 citations 数组进行升序排序。例如,对于输入数组 [3,0,6,1,5],排序后会变成 [0,1,3,5,6] 。排序的时间复杂度为 O(nlog⁡n)O(n\log n)O(nlogn) ,其中 n 是数组的长度,这是由排序算法的时间复杂度决定的(Java 中 Arrays.sort 对于基本数据类型数组采用的是优化的快速排序等算法,平均时间复杂度为 O(nlog⁡n)O(n\log n)O(nlogn) )。

  1. 遍历判断过程
int n = citations.length; 
for (int i = 0; i < n; i++) { if (citations[i] >= n - i) { return n - i; }
}
  • 首先获取数组长度 n ,代表论文的总篇数。
  • 然后进入循环遍历,i 从 0 开始递增到 n - 1 。对于每一个 i ,计算 n - i ,这个值代表的是假设的 h 值,含义是当前考虑有 n - i 篇论文可能满足引用次数 ≥ n - i 。
  • 因为数组是升序排序的,citations[i] 是第 i + 1 小的引用次数(数组索引从 0 开始 ),当 citations[i] >= n - i 时,说明从第 i 篇论文开始(包括第 i 篇 ),后面一共有 n - i 篇论文(索引从 i 到 n - 1 ),它们的引用次数都大于等于 citations[i] ,自然也大于等于 n - i (因为 citations[i] >= n - i 且数组升序 )。所以此时 n - i 就是满足条件的 H 指数,直接返回即可。这是因为我们是从前往后遍历,一旦找到第一个满足条件的 i ,对应的 n - i 就是最大的可能的 H 指数。比如排序后的数组 [0,1,3,5,6] ,n = 5 ,当 i = 2 时,n - i = 3 ,citations[2] = 3 ,满足 citations[i] >= n - i ,所以返回 3 ,也就是正确的 H 指数。
  1. 返回默认值
return 0; 

如果循环遍历结束后,没有找到满足 citations[i] >= n - i 的情况,说明所有论文的引用次数都非常低,比如数组全为 0 ,此时 H 指数为 0 ,所以返回 0 。

四、算法的时间复杂度和空间复杂度分析

(一)时间复杂度

  • 排序操作的时间复杂度:使用 Arrays.sort 对数组进行排序,其时间复杂度为 O(nlog⁡n)O(n\log n)O(nlogn) ,其中 n 是数组 citations 的长度。
  • 线性遍历的时间复杂度:排序后进行的线性遍历,时间复杂度为 O(n)O(n)O(n) ,n 同样是数组长度。

所以,整个算法的时间复杂度由排序操作主导,为 O(nlog⁡n)O(n\log n)O(nlogn)

(二)空间复杂度

  • 排序操作在 Java 中,对于基本数据类型数组的 Arrays.sort 方法,采用的是原地排序(大部分情况下 ),不需要额外的大量空间,空间复杂度为 O(log⁡n)O(\log n)O(logn) (主要是排序过程中递归调用栈或者用于辅助排序的空间,基于快速排序等算法的实现 )。
  • 其他变量如 n 、i 等都是常数级别的空间占用。

所以,整个算法的空间复杂度为 O(log⁡n)O(\log n)O(logn) (主要由排序操作决定 ),在大多数情况下可以认为是较为高效的空间利用。

http://www.dtcms.com/a/324598.html

相关文章:

  • Mysql 8.0 新特性
  • 以太网相关协议
  • C/C++数据结构之双向链表
  • scala 样例类
  • Spring的三层架构及其各个层用到注解详细解释。
  • 零基础学Java第三讲---运算符
  • android 使用openimagelib OpenImage 实现点击放大图片,浏览
  • 【Docker实战】Spring Boot应用容器化
  • 蓝牙认证流程:BQB 测试、互操作性验证与品牌授权指南 —— 面试高频考点与历年真题解
  • Bean的实例化方式
  • WinForm之TreeView控件
  • 深入解析React Diff 算法
  • 基于 InfluxDB 的服务器性能监控系统实战(三)
  • Windchill 11.0使用枚举类型自定义实用程序实现角色管理
  • Web API开发中的数据传输:MIME类型配置与编码最佳实践
  • vulnhub-Doubletrouble靶机
  • 医学统计(随机对照研究分类变量结局数据的统计策略3)
  • AI正自我觉醒!
  • C4.5算法:增益率(Gain Ratio)
  • 洛谷 P2404 自然数的拆分问题-普及-
  • 3.3keep-alive
  • Windows11 [Close Folder Shortcut]
  • vue2升级vue3:单文件组件概述 及常用api
  • Android Intent 解析
  • 【Linux】通俗易懂讲解-正则表达式
  • 从Redisson源码角度深入理解Redis分布式锁的正确实现
  • JetPack系列教程(三):Lifecycle——给Activity和Fragment装个“生命探测仪“
  • redis主从模型与对象模型
  • Beelzebub靶机练习
  • 代码随想录算法训练营第五十九天|图论part9