Nameless Site

But one day, you will stand before its decrepit gate,without really knowing why.

0%

H指数

来自Leetcode第274题H指数

给定一位研究者论文被引用次数的数组(被引用次数是非负整数)。编写一个方法,计算出研究者的 h 指数。

h 指数的定义: “h 代表“高引用次数”(high citations),一名科研人员的 h 指数是指他(她)的 (N 篇论文中)至多有 h 篇论文分别被引用了至少 h 次。(其余的 N - h 篇论文每篇被引用次数不多于 h 次。)”

示例:

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

说明: 如果 h 有多种可能的值,h 指数是其中最大的那个。


排序

来源题解

我们想象一个直方图,其中 x 轴表示文章,y 轴表示每篇文章的引用次数。如果将这些文章按照引用次数降序排序并在直方图上进行表示,那么直方图上的最大的正方形的边长 h 就是我们所要求的 h

h-index

首先我们将引用次数降序排序,在排完序的数组citations 中,如果 citations[i]>i,那么说明第 0 到 i 篇论文都有至少 i+1 次引用。因此我们只要找到最大的 i满足 citations[i]>i*,那么 h 指数即为 i+1。

1
2
3
4
5
6
7
8
9
10
public int hIndex(int[] citations) {
Arrays.sort(citations);
int h = 0;
for(int i = 0 ; i < citations.length ;i++){
h = citations.length - i;
if( h <= citations[i])
return h;
}
return 0;
}

计数

来源题解

要得到时间复杂度更低的算法. 可以考虑最常用的不基于比较的排序,计数排序

然而,论文的引用次数可能会非常多,这个数值很可能会超过论文的总数 n,因此使用计数排序是非常不合算的(会超出空间限制)。在这道题中,我们可以通过一个不难发现的结论来让计数排序变得有用,即:

如果一篇文章的引用次数超过论文的总数 n,那么将它的引用次数降低为 n 也不会改变 h 指数的值。

由于 h 指数一定小于等于 n,因此这样做是正确的。在直方图中,将所有超过 y 轴值大于 n 的变为 n 等价于去掉 y>n 的整个区域。

h-index cut off

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Solution {
public int hIndex(int[] citations) {
int n = citations.length;
int[] papers = new int[n + 1];
// 计数
for (int c: citations)
papers[Math.min(n, c)]++;
// 找出最大的 k
int k = n;
for (int s = papers[n]; k > s; s += papers[k])
k--;
return k;
}
}