Medium
题目描述
给你一个整数数组 citations,其中 citations[i] 表示研究者第 i 篇论文被引用的次数。计算并返回该研究者的 h 指数。
根据维基百科上 h 指数 的定义:h 指数是能够同时满足下述两个条件的最大值 h:
- 该研究者至少有
h篇论文分别被引用了至少h次。 - 其余的
N - 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.length1 <= n <= 50000 <= citations[i] <= 1000
解题思路
这道题要找到最大的 h 值,使得至少有 h 篇论文被引用了至少 h 次。
方法一:排序法
将引用次数从大到小排序,然后遍历数组。对于第 i 篇论文(从0开始),如果 citations[i] >= i+1,说明至少有 i+1 篇论文被引用了至少 i+1 次。我们要找的是满足条件的最大值。
方法二:计数排序法(推荐) 由于 h 指数的最大值不会超过论文总数 n,我们可以用计数数组统计每个引用次数的论文数量。然后从高到低累计,找到第一个满足"至少有 h 篇论文被引用至少 h 次"的位置。
计数排序法的优势是时间复杂度更优,特别适合这道题的数据范围。我们创建一个大小为 n+1 的数组,将所有大于等于 n 的引用次数都计入 bucket[n] 中(因为 h 指数最大就是 n)。
算法步骤:
- 创建计数数组,统计各引用次数的论文数量
- 从后往前累计,计算至少被引用 i 次的论文总数
- 找到最大的 h,使得至少有 h 篇论文被引用至少 h 次
代码实现
class Solution {
public:
int hIndex(vector<int>& citations) {
int n = citations.size();
vector<int> bucket(n + 1, 0);
// 计数:统计每个引用次数的论文数量
for (int citation : citations) {
if (citation >= n) {
bucket[n]++;
} else {
bucket[citation]++;
}
}
// 从后往前累计,找到h指数
int count = 0;
for (int i = n; i >= 0; i--) {
count += bucket[i];
if (count >= i) {
return i;
}
}
return 0;
}
};
class Solution:
def hIndex(self, citations: List[int]) -> int:
n = len(citations)
bucket = [0] * (n + 1)
# 计数:统计每个引用次数的论文数量
for citation in citations:
if citation >= n:
bucket[n] += 1
else:
bucket[citation] += 1
# 从后往前累计,找到h指数
count = 0
for i in range(n, -1, -1):
count += bucket[i]
if count >= i:
return i
return 0
public class Solution {
public int HIndex(int[] citations) {
int n = citations.Length;
int[] bucket = new int[n + 1];
// 计数:统计每个引用次数的论文数量
foreach (int citation in citations) {
if (citation >= n) {
bucket[n]++;
} else {
bucket[citation]++;
}
}
// 从后往前累计,找到h指数
int count = 0;
for (int i = n; i >= 0; i--) {
count += bucket[i];
if (count >= i) {
return i;
}
}
return 0;
}
}
var hIndex = function(citations) {
const n = citations.length;
const bucket = new Array(n + 1).fill(0);
// 计数:统计每个引用次数的论文数量
for (const citation of citations) {
if (citation >= n) {
bucket[n]++;
} else {
bucket[citation]++;
}
}
// 从后往前累计,找到h指数
let count = 0;
for (let i = n; i >= 0; i--) {
count += bucket[i];
if (count >= i) {
return i;
}
}
return 0;
};
复杂度分析
| 复杂度 | 计数排序法 | 排序法 |
|---|---|---|
| 时间复杂度 | O(n) | O(n log n) |
| 空间复杂度 | O(n) | O(1) |
相关题目
- . H-Index II (Medium)