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

Leetcode经典题8--H指数

题目描述:

给你一个整数数组 citations ,其中 citations[i] 表示研究者的第 i 篇论文被引用的次数。计算并返回该研究者的 h 指数。

根据维基百科上 h 指数的定义:h 代表“高引用次数” ,一名科研人员的 h 指数 是指他(她)至少发表了 h 篇论文,并且 至少 有 h 篇论文被引用次数大于等于 h 。如果 h 有多种可能的值,h 指数 是其中最大的那个。

输入输出示例 :

输入:citations = [3,0,6,1,5]

输出:3

解释:给定数组表示研究者总共有 5 篇论文,每篇论文相应的被引用了 3, 0, 6, 1, 5 次。

  由于研究者有 3 篇论文每篇 至少 被引用了 3 次,其余两篇论文每篇被引用 不多于 3 次,所以她的 h 指数是 3。

解题方案:

方式一:排序

算法思想:首先我们将初始的H指数h设置为0,然后将每个文章的引用次数排序,并且对数组进行从大到小的遍历,如果在遍历过程中找到当前值 citations[i]>h,那么对于i后面的n-i-1个数,肯定都大于h,可定有h+1

举例说明:

例如对于下面的数组

[3,0,6,1,5]

首先进行排序

0 1 3 5 6

然后我们从后往前遍历(数值上从大到小遍历)

初始h=0 此时指向数值6 6>0 所以h=1 至少有1个文章的引用次数大于1

指向数值5 5>1 所以h=2 此时已经倒序遍历了2个数,如果当前数大于2,那么至少有2个文章的引用次数(两篇遍历过的文章的引用次数5次,和6次)大于2

指向数值3 3>2 所以h=3 此时已经倒序遍历了3个数,如果当前数大于3,那么至少有3个文章的引用次数(3篇遍历过的文章的引用次数3次 5次,和6次)大于2

实现代码:

class Solution {
    public int hIndex(int[] citations) {
        Arrays.sort(citations);//将数组排序
        int h = 0, i = citations.length - 1; //从后往前遍历
        while (i >= 0 && citations[i] > h) {
            h++; 
            i--;
        }
        return h;
    }
}

复杂度分析

时间复杂度:O(nlogn),

其中 n 为数组 citations 的长度。即为排序的时间复杂度。

空间复杂度:O(logn),

其中 n 为数组 citations 的长度。即为排序的空间复杂度。

方法二:计数排序

算法思想:使用计数排序算法,新建并维护一个数组 counter 用来记录当前引用次数的论文有几篇。

根据定义,我们可以发现 H 指数不可能大于总的论文发表数,所以对于引用次数超过论文发表数的情况,我们可以将其按照总的论文发表数来计算即可。这样我们可以限制统计引用次数的数组大小为 [0,n](其中 n 为总的论文发表数),使得计数排序的时间复杂度降低到 O(n)。

最后我们可以从后向前遍历数组 counter,对于每个 0≤i≤n,在数组 counter 中得到大于或等于当前引用次数 i 的总论文数。当我们找到一个 H 指数时跳出循环,并返回结果。

实现代码:

class Solution {
    public int hIndex(int[] citations) {
        //n记录数组长度和最多的引用次数 tot记录大于某个引用次数的论文数
        int n=citations.length,tot=0;
        int[] counter=new int[n+1];//每个引用次数对应的论文数
        for(int i=0;i<n;i++){
            if(citations[i]>=n){
                counter[n]++;
            }else{
                counter[citations[i]]++;
            }
        }

        for(int i=n;i>=0;i--){
            tot+=counter[i];
            if(tot>=i){
                return i;
            }
            
        }
       return 0;
    }
}

复杂度分析:

时间复杂度:O(n),

其中 n 为数组 citations 的长度。需要遍历数组 citations 一次,以及遍历长度为 n+1 的数组 counter 一次。

空间复杂度:O(n),

其中 n 为数组 citations 的长度。需要创建长度为 n+1 的数组 counter。

方式三:二分搜索

算法思想:我们需要找到一个值 h,它是满足「有 h 篇论文的引用次数至少为 h」的最大值。小于等于 h 的所有值 x 都满足这个性质,而大于 h 的值都不满足这个性质。同时因为我们可以用较短时间(扫描一遍数组的时间复杂度为 O(n),其中 n 为数组 citations 的长度)来判断 x 是否满足这个性质,所以这个问题可以用二分搜索来解决。

设查找范围的初始左边界 left 为 0,初始右边界 right 为 n。每次在查找范围内取中点 mid,同时扫描整个数组,判断是否至少有 mid 个数大于 mid。如果有,说明要寻找的 h 在搜索区间的右边,反之则在左边。

实现代码

class Solution {
    public int hIndex(int[] citations) {
        int left=0,right=citations.length;
        int mid=0,cnt=0;
        while(left<right){
            // +1 防止死循环
            mid=(left+right+1)>>1;
            cnt=0;
            for(int i=0;i<citations.length;i++){
                if(citations[i]>=mid){
                    cnt++;
                }
            }
            if(cnt>=mid){
                // 要找的答案在 [mid,right] 区间内
                left=mid;
            }else{
                // 要找的答案在 [0,mid) 区间内
                right=mid-1;
            }
        }
        return left;
    }
}

复杂度分析

时间复杂度:O(nlogn),

其中 n 为数组 citations 的长度。需要进行 logn 次二分搜索,每次二分搜索需要遍历数组 citations 一次。

空间复杂度:O(1),

只需要常数个变量来进行二分搜索。


http://www.kler.cn/a/441579.html

相关文章:

  • 10倍数据交付提升 | 通过逻辑数据仓库和数据编织高效管理和利用大数据
  • 实战经验:使用 Python 的 PyPDF 进行 PDF 操作
  • AIGC视频生成模型:ByteDance的PixelDance模型
  • Qt —— 控件属性
  • Java 中的设计模式:经典与现代实践
  • CMake技术细节:解决未定义,提供参数
  • 深度学习之Autoencoders GANs for Anomaly Detection 视频异常检测
  • xshell连接虚拟机,更换网络模式:NAT->桥接模式
  • SpringBoot集成ENC对配置文件进行加密
  • 阶段性demo 键盘信息过滤
  • 天猫魔盒M17/M17S_超级UI 线刷固件包-可救砖(刷机取消双勾)
  • 【HF设计模式】03-装饰者模式
  • Transformer 中 Self-Attention 的二次方复杂度(Quadratic Complexity )问题及改进方法:中英双语
  • 【Flink-scala】DataStream编程模型总结
  • 2025山东科技大学考研专业课复习资料一览
  • Java设计模式实战:策略模式、工厂模式、模板模式组合使用
  • 人工智能浪潮来袭:2024年技术革命与产业变革深度解析@附64页PDF文件下载
  • 基于Android的生活记录app的设计与实现
  • 【教程】让Jupyter支持打开CSV和Excel(xlsx)文件
  • 死信队列概述
  • 【Leetcode】滑动窗口算法-编程苍穹下划破数据暗夜的高效光弧
  • pytest入门九:feature
  • 【Hive 如何进行update更新?】
  • “MODAS: 利用多组学数据关联研究探索玉米种质资源“
  • elasticsearch 版本
  • [机器学习]AdaBoost(数学原理 + 例子解释 + 代码实战)