Leetcode274.H指数
题目描述:
给定一位研究者论文被引用次数的数组(被引用次数是非负整数)。编写一个方法,计算出研究者的 h 指数。
h 指数的定义: “h 代表“高引用次数”(high citations),一名科研人员的 h 指数是指他(她)的 (N 篇论文中)至多有 h 篇论文分别被引用了至少 h 次。(其余的 N - h 篇论文每篇被引用次数不多于 h 次。)”
示例:
输入: citations = [3,0,6,1,5]
输出: 3
解释: 给定数组表示研究者总共有 5 篇论文,每篇论文相应的被引用了 3, 0, 6, 1, 5 次。
由于研究者有 3 篇论文每篇至少被引用了 3 次,其余两篇论文每篇被引用不多于 3 次,所以她的 h 指数是 3。
说明:
如果 h 有多种可能的值,h 指数是其中最大的那个。
解答思路1
对数据进行排序,当索引i
位置的值大于N-i
(即包含所处位置以及后面数据的个数)时,满足条件。
class Solution(object):
def hIndex(self, citations):
"""
:type citations: List[int]
:rtype: int
"""
count = len(citations)
citations.sort()
temp = float('-inf')
for i in range(count):
if citations[i] >= count - i:
temp = max(temp, count - i)
if temp != float('-inf'):
return temp
else:
return 0
解答思路2(计数)
源自官方解答:https://leetcode-cn.com/problems/h-index/solution/hzhi-shu-by-leetcode/
分析
基于比较的排序算法存在时间复杂度下界 O(n\log n)O(nlogn),如果要得到时间复杂度更低的算法,就必须考虑不基于比较的排序。
算法
方法一中,我们通过降序排序得到了 hh 指数,然而,所有基于比较的排序算法,例如堆排序,合并排序和快速排序,都存在时间复杂度下界 O(nlogn)。要得到时间复杂度更低的算法. 可以考虑最常用的不基于比较的排序,计数排序。
然而,论文的引用次数可能会非常多,这个数值很可能会超过论文的总数 nn,因此使用计数排序是非常不合算的(会超出空间限制)。在这道题中,我们可以通过一个不难发现的结论来让计数排序变得有用,即:
如果一篇文章的引用次数超过论文的总数 n,那么将它的引用次数降低为 n 也不会改变 h 指数的值。
由于 h 指数一定小于等于 n,因此这样做是正确的。在直方图中,将所有超过 y 轴值大于 n 的变为 n 等价于去掉 y>n 的整个区域。
从直方图中可以更明显地看出结论的正确性,将 y>n 的区域去除,并不会影响到最大的正方形,也就不会影响到 h 指数。
我们用一个例子来说明如何使用计数排序得到 h 指数。首先,引用次数如下所示:
citations=[1, 3, 2, 3, 100]
将所有大于 n=5 的引用次数变为 n,得到:
citations = [1, 3, 2, 3, 5]
计数排序得到的结果如下:
k | 0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|
count | 0 | 1 | 1 | 2 | 0 | 1 |
s_k | 5 | 5 | 4 | 3 | 1 | 1 |
其中 s_k 表示至少有 k 次引用的论文数量,在表中即为在它之后的列(包括本身)的 count 一行的和。根据定义,最大的满足 k ≤ s_k 的 k 即为所求的 h。在表中,这个 k 为 3,因此 h 指数为 3。
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;
复杂度分析
时间复杂度:O(n)。在计数时,我们仅需要遍历 citations 数组一次,因此时间复杂度为 O(n)。在找出最大的 k 时,我们最多需要遍历计数的数组一次,而计数的数组的长度为 O(n),因此这一步的时间复杂度为 O(n),即总的时间复杂度为 O(n)。
空间复杂度:O(n)。我们需要使用 O(n) 的空间来存放计数的结果。