LinQinの博客空间
首页项目归档照片墙音乐灵境说说杂谈友链关于
封面

LeetCode 面试经典150题

写作时间:2026-09-15 17:39:17

274. H 指数

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

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

示例 1:

输入:citations = [3,0,6,1,5]
输出:3 
解释:给定数组表示研究者总共有 5 篇论文,每篇论文相应的被引用了 3, 0, 6, 1, 5 次。
     由于研究者有 3 篇论文每篇 至少 被引用了 3 次,其余两篇论文每篇被引用 不多于 3 次,所以她的 h 指数是 3。

示例 2:

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

提示:

  • n == citations.length
  • 1 <= n <= 5000
  • 0 <= citations[i] <= 1000

题意:

给你一个数组,求一个最大的 h,使得数组中有至少 h 个数都大于等于 h。


‍

本题可以做到 O(n) 时间。

设 n 为 citations 的长度,即这名研究者发表的论文数。根据题意,h 不可能超过 n,所以对于引用次数大于 n 的论文,我们在统计的时候,可以看成是引用次数等于 n 的论文。例如 n=5,假设 h 是 5,那么无论引用次数是 6 还是 5,都满足 ≥5,所以 6 可以看成是 5,毕竟我们只需要统计有多少个数字是 ≥5 的。

所以,创建一个长为 n+1 的 cnt 数组,统计 min(citations[i],n) 的出现次数。

设 s 为引用次数 ≥i 的论文数,我们需要算出满足 s≥i 的最大的 i。

为了快速算出有多少论文的引用次数 ≥i,我们可以从 i=n 开始倒序循环,每次循环,把 cnt[i] 加到 s 中。由于我们是倒序循环的,只要 s≥i 成立,此时的 i 就是满足 s≥i 的最大的 i,直接返回 i 作为答案。

例如示例 1,从 i=5 开始:

i=5,现在 s=2<i,继续循环。

i=4,现在 s=2<i,继续循环。

i=3,现在 s=3≥i,返回 3。

class Solution {
    public int hIndex(int[] citations) {
        int n = citations.length;
        int[] cnt = new int[n + 1]; //创建一个数组,大小为n+1,即0,1,2...n共n+1,用于存储对应下标对应的引用次数
//比如`[3,0,6,1,5]`,引用0次→1,引用1次→1,引用2次→0,引用 3 次 →1,引用4次→ 0,引用5次→2(5和6都算作5);
// 所以最后数组为[1,1,0,1,0,2]
        for (int c : citations) {
            cnt[Math.min(c, n)]++; // 引用次数 > n,等价于引用次数为 n
        }
        int s = 0;
        // i--:倒着累加,直到s>i
//如:如果h=5 👉 但是cnt[5]=2 <5 所以不成立
// 如果 h =4 但是 2+cnt[4] = 2 <4 所以还是不成立
// 轮到 h=3 2+cut[3] = 3 = 3 所以成立了,h=3,就 return i;
        for (int i = n; ; i--) { // i=0 的时候,s>=i 一定成立
            s += cnt[i];
            if (s >= i) { // 说明有至少 i 篇论文的引用次数至少为 i
                return i;
            }
        }
    }
}

复杂度分析

  • 时间复杂度:O(n),其中 n 为 citations 的长度。
  • 空间复杂度:O(n)。

‍

作者:灵茶山艾府

链接:https://leetcode.cn/problems/h-index/solutions/2502837/mei-kan-dong-ti-yi-yi-zhang-tu-miao-dong-8zps/

来源:力扣(LeetCode)

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


但是这个解法有点难,我选择另一个解法:

时间复杂度为O(nlogn),但是会简单很多:

逆序排序

比如排序后[6, 5, 3, 1, 0],如果 citations[i] > i,那么前面的数必定大于i,所以找到i的最大值就是答案,因为 i从0开始,所以返回结果需要i+1

class Solution {
    public int hIndex(int[] citations) {
        Arrays.sort(citations);
        int n = citations.length;
        for (int i = 0; i < n; i++) {
            // 当前位置及后面共有 n - i 篇论文
            if (citations[i] >= n - i) {
                return n - i;
            }
        }
        return 0;
    }
}

‍

avatar

LinQin

内陆某双非院校软件工程专业本科生,方向为后端开发,互联网边缘地带人员。

RECOMMENDED

Hello

2026-03-24 07:00:45

LeetCode 面试经典150题

2026-09-14 16:57:12

LeetCode 面试经典150题

2026-09-17 11:51:03

Table of Contents