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

结果

运行代码,测试通过:

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

总结

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

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

加油!!!

相关推荐
艾伦~耶格尔3 分钟前
常用Java API
java·开发语言·学习
武子康4 分钟前
大数据-131 - Flink CEP 案例:检测交易活跃用户、超时未交付
java·大数据·flink·spark·scala
LazySideny32 分钟前
Maven创建项目中的groupId, artifactId, 和 version的意思
java·maven
软件测试雪儿36 分钟前
2024软件测试自动化面试题(含答案)
软件测试·面试·自动化·软件测试面试
wangsir.43 分钟前
进程间通信-进程池
linux·开发语言·算法
虾小眠05261 小时前
python 100个算法
python·算法
qq_1873526341 小时前
迭代求方程的根c++
c++·算法·迭代求方程的根c++
闲人编程1 小时前
Python实现人工免疫系统算法
开发语言·python·算法·优化·ais·人工免疫
Letmooning1 小时前
[机器学习]聚类算法
算法·机器学习·聚类