力扣面试经典算法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);
    } }

结果

运行代码,测试通过:

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

总结

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

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

加油!!!

相关推荐
杉之2 分钟前
Java中的不可变集合
java·笔记·学习
舔甜歌姬的EGUMI LEGACY5 分钟前
【算法day28】解数独——编写一个程序,通过填充空格来解决数独问题
算法
潘多编程5 分钟前
Gradle实战指南:从入门到进阶,与Maven的深度对比
java·maven
故城、7 分钟前
MQ中的RabbitMQ
java·mq
welkin18 分钟前
KMP 个人理解
前端·算法
橘猫云计算机设计23 分钟前
基于JavaWeb的二手图书交易系统(源码+lw+部署文档+讲解),源码可白嫖!
java·开发语言·前端·毕业设计·php
猿java24 分钟前
程序员,你使用过灰度发布吗?
java·分布式·后端
半桔24 分钟前
红黑树剖析
c语言·开发语言·数据结构·c++·后端·算法
我的div丢了肿么办24 分钟前
vue3第二次传递数据方法无法获取到最新的值
前端·面试·github
兰亭序咖啡26 分钟前
学透Spring Boot — 007. 加载外部配置
android·java·spring boot