H指数
1. 概述
-
根据百度百科定义:
-
H指数(
H index
):一名科研人员的 H 指数是指他(她)的 (n
篇论文中)总共有h
篇论文分别被引用了大于等于h
次。且其余的n - h
篇论文每篇被引用次数小于等于h
次。
2. 例题
Leetcode 0274 H指数
题目描述:Leetcode 0274 H指数
分析
-
本题的考点:排序。
-
将数组从大到小排序,然后根据引用次数从高到低是否有符合要求的论文即可。
代码
- C++
class Solution {
public:
int hIndex(vector<int> &c) {
int n = c.size();
sort(c.begin(), c.end());
for (int h = n; h; h--)
if (c[n - h] >= h)
return h;
return 0;
}
};
class Solution {
public:
int hIndex(vector<int> &c) {
sort(c.begin(), c.end(), greater<int>()); // 从大到小排列
for (int h = c.size(); h; h--)
if (c[h - 1] >= h)
return h;
return 0;
}
};
- Java
class Solution {
public int hIndex(int[] c) {
Arrays.sort(c);
for (int h = c.length; h > 0; h--)
if (c[c.length - h] >= h)
return h;
return 0;
}
}
- Python
class Solution:
def hIndex(self, cs: List[int]) -> int:
cs.sort(reverse=True)
for h in range(len(cs), 0, -1):
if cs[h - 1] >= h:
return h
return 0
时空复杂度分析
-
时间复杂度: O ( n × l o g ( n ) ) O(n \times log(n)) O(n×log(n)),
n
为数组长度。 -
空间复杂度: O ( 1 ) O(1) O(1)。
Leetcode 0275 H指数 II
题目描述:Leetcode 0275 H指数 II
分析
-
本题的考点:二分查找。
-
因为数组是从小到大排好序的,我们每次可以在区间
[0, n]
中搜索答案,每次取中点mid
,如果有citations[n-mid]>=mid
,说明n-mid ~ n-1
这mid
篇论文的引用次数大于mid
次,是一个符合要求的答案,可以更新左端点,否则更新右端点。
代码
- C++
class Solution {
public:
int hIndex(vector<int> &c) {
int n = c.size();
int l = 0, r = n;
while (l < r) {
int mid = l + r + 1 >> 1;
if (c[n - mid] >= mid) l = mid;
else r = mid - 1;
}
return r;
}
};
- Java
class Solution {
public int hIndex(int[] c) {
int n = c.length;
int l = 0, r = n;
while (l < r) {
int mid = l + r + 1 >> 1;
if (c[n - mid] >= mid) l = mid;
else r = mid - 1;
}
return r;
}
}
- Python
class Solution:
def hIndex(self, cs: List[int]) -> int:
n = len(cs)
l, r = 0, n
while l < r:
mid = l + r + 1 >> 1
if cs[n - mid] >= mid:
l = mid
else:
r = mid - 1
return r
时空复杂度分析
-
时间复杂度: O ( l o g ( n ) ) O(log(n)) O(log(n)),
n
为数组长度。 -
空间复杂度: O ( 1 ) O(1) O(1)。
AcWing 1158. H指数
问题描述
-
问题链接:AcWing 1158. H指数
分析
-
我们需要动态的求出所有
H
指数,每添加一篇文章,都需要计算对应的H
指数。 -
首先,可以发现
H
指数一定是非递减的,多发一篇文章不会让H
指数变小。 -
H
指数是一个边界,考虑如果将数组排序后,后面的H
个数一定大于等于H
,前面的数都小于等于H
。 -
这里使用一个小根堆将当前满足
H
指数的数存储下来。然后考虑如果插入一个数,应该如何更新小根堆。 -
使用变量
res
记录每次加入一个数后的答案,初始为零。假设当前加入的数为x
,如果x<=res
,则不会让结果变大,直接忽略;如果x>res
,则将x
加入到堆中,然后把堆中等于res
的数都删掉,之后堆中存储的都是严格大于res
的数,如果此时堆中元素个数严格大于res
,结果加一。
代码
- C++
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
int main() {
int T;
scanf("%d", &T);
for (int C = 1; C <= T; C++) {
printf("Case #%d: ", C);
priority_queue<int, vector<int>, greater<int>> heap;
int n;
scanf("%d", &n);
int res = 0;
while (n--) {
int x;
scanf("%d", &x);
if (x > res) heap.push(x);
while (heap.size() && heap.top() == res) heap.pop();
if (heap.size() > res) res++;
printf("%d ", res);
}
puts("");
}
return 0;
}