力扣面试经典算法150题:H 指数

H 指数

今天的题目是力扣面试经典150题中的数组的中等难度题: H 指数。

题目链接:https://leetcode.cn/problems/h-index/description/?envType=study-plan-v2&envId=top-interview-150

题目内容

给定一位研究者论文被引用次数的数组 citations,数组中的每个元素 citations[i] 表示研究者的第 i 篇论文被引用的次数。计算并返回研究者的 H 指数。

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

  • 示例 1:

    • 输入:
      citations = [3,0,6,1,5]
    • 输出:
      3
  • 示例 2:

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

题目分析

题目要求我们根据论文引用次数数组计算研究者的 H 指数。那么我们首先要理解什么是H指数。

我们看看示例。

第一个示例输出3,我们简单找一下规律,数组中citations中大于等于3的元素是不是有3个?是不是有点符合题目中的h篇论文与h次。

我们再看第二个示例,输出了1。 数组citations中大于等于1的元素有三个啊,怎么输出1呢?

这里说明我们对目前题目内容的总结还不到位,继续分析。根据题目中指数定义,h的值三个条件都要满足,很明显我们简单分析过于简单。

这里我们有点陷入了误区,尤其是在第二个示例中,那么我们对示例重新分析,这次我们严格按照规则来分析,重点是两个h。

示例一分析

citations = [3,0,6,1,5]

我们从论文数开始,网上累加:

  1. h = 1,最少发布1篇论文,最少有1篇论文被引用1次。 发布5篇,有4篇被引用1次以上,h=1成立。
  2. h = 2,最少发布2篇论文,最少有2篇论文被引用2次。 发布5篇,有3篇被引用2次以上,h=2成立。
  3. h = 3,最少发布3篇论文,最少有3篇论文被引用3次。 发布5篇,有3篇被引用3次以上,h=3成立。
  4. h = 4,最少发布4篇论文,最少有4篇论文被引用4次。 发布5篇,有2篇被引用4次以上,h=4不成立。
  5. 后续更大的h值不会再成立了。

那么,示例一输出h = 3,是不是符合?

示例二分析

citations = [1,3,1]

参考示例一的分析,我们对示例二进行分析:

  1. h = 1,最少发布1篇论文,最少有1篇论文被引用1次。 发布3篇,有3篇被引用1次以上,h=1成立。
  2. h = 2,最少发布2篇论文,最少有2篇论文被引用2次。 发布3篇,有1篇被引用2次以上,h=2不成立。
  3. 后续更大的h值不会再成立了。

这么一看,示例二的输出1就明白了吧。

解题思路

这个题目简单粗暴的话就是直接暴力破解,暴力破解的思路比较直接简单,就是简单直接遍历,一个个开始试,就想示例分析的那样。但是这种方式对于大数组明显不现实,所以我们还得另想办法。

在上面的分析中,我们再次分析。可以发现解题需要对元素的值进行比较,并且需要抛弃或者说保留临界值另一边的数据。

那么我们直接排序,然后解答的时候,直接查看大于h值那边的元素个数,与h一比,不就行了?

也就是说我们需要一个方法,根据某个值来分开数组进行统计。

少侠,有没有听过二分法?

二分法

简单介绍一下二分法:

二分查找算法,又称折半查找算法,是一种在有序数组中查找特定元素的高效搜索方法。其核心思想是将目标值与数组中间元素进行比较,根据比较结果缩小搜索范围,然后重复这个过程,直到找到目标值或搜索范围为空。

基本步骤:

  • 初始化:设置两个指针,一个指向数组的起始位置(通常记为low),另一个指向数组的结束位置(通常记为high)。

  • 比较:取中间位置的元素(mid),将其与目标值进行比较。

  • 判断:

    • 如果中间元素等于目标值,搜索成功,返回该位置。
    • 如果中间元素大于目标值,说明目标值位于数组的前半部分,更新high为mid - 1。
    • 如果中间元素小于目标值,说明目标值位于数组的后半部分,更新low为mid + 1。
  • 重复:继续步骤2和3,直到low大于high,此时搜索失败,目标值不在数组中。

实际算法代码

以下是使用上述思路的 Java 实现:

java 复制代码
public class Solution {
    public int hIndex(int[] citations) {
        Arrays.sort(citations);

        int n = citations.length;
        int hIndex = 0;

        for (int i = n - 1; i >= 0; i--) {
            int h = n - i;
            if (citations[i] >= h) {
                hIndex = h;
            } else {
                break;
            }
        }

        return hIndex;
    }

    public static void main(String[] args) {
        Solution solution = new Solution();
        int[] citations = {3, 0, 6, 1, 5};
        int hIndex = solution.hIndex(citations);
        System.out.println("H index: " + hIndex);
    } }

结果

运行代码,测试通过:

提交到力扣,也正常通过:

总结

今天的题目使用了新的算法,二分法,本文只是简单的介绍了一下什么是二分法已经步骤。

相比与暴力解答,二分法明显时间复杂度更低,并且使用时对大数组也相对支持。大家可以自己另外学习二分法,也可以等我后面总结学习。

加油!!!

相关推荐
轻抚酸~1 小时前
小迪23年-32~40——java简单回顾
java·web安全
Sirius Wu3 小时前
Maven环境如何正确配置
java·maven
健康平安的活着4 小时前
java之 junit4单元测试Mockito的使用
java·开发语言·单元测试
No0d1es4 小时前
电子学会青少年软件编程(C/C++)5级等级考试真题试卷(2024年6月)
c语言·c++·算法·青少年编程·电子学会·五级
Java小白程序员5 小时前
Spring Framework :IoC 容器的原理与实践
java·后端·spring
xuTao6675 小时前
Easy Rules 规则引擎详解
java·easy rules
m0_480502646 小时前
Rust 入门 KV存储HashMap (十七)
java·开发语言·rust
大阳1236 小时前
线程(基本概念和相关命令)
开发语言·数据结构·经验分享·算法·线程·学习经验
杨DaB6 小时前
【SpringBoot】Swagger 接口工具
java·spring boot·后端·restful·swagger
YA3336 小时前
java基础(九)sql基础及索引
java·开发语言·sql