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

结果

运行代码,测试通过:

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

总结

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

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

加油!!!

相关推荐
confiself10 分钟前
大模型系列——LLAMA-O1 复刻代码解读
java·开发语言
Wlq041515 分钟前
J2EE平台
java·java-ee
ZL不懂前端16 分钟前
Content Security Policy (CSP)
前端·javascript·面试
XiaoLeisj22 分钟前
【JavaEE初阶 — 多线程】Thread类的方法&线程生命周期
java·开发语言·java-ee
为什么这亚子31 分钟前
九、Go语言快速入门之map
运维·开发语言·后端·算法·云原生·golang·云计算
豪宇刘37 分钟前
SpringBoot+Shiro权限管理
java·spring boot·spring
41 分钟前
开源竞争-数据驱动成长-11/05-大专生的思考
人工智能·笔记·学习·算法·机器学习
Elaine20239141 分钟前
02多线程基础知识
java·多线程
gorgor在码农43 分钟前
Redis 热key总结
java·redis·热key
~yY…s<#>1 小时前
【刷题17】最小栈、栈的压入弹出、逆波兰表达式
c语言·数据结构·c++·算法·leetcode