h-index
2019-11-22 14:10:19
Google kickstart 2019 h round 的A题是h-index,leetcode上也有两条相关问题,本次对h-index问题做一个汇总。
- 274. H-Index
问题描述:

问题求解:
h-index描述:至少有h篇论文的引用数量大于等于h。
解法一:排序
我们想象一个直方图,其中 xx 轴表示文章,yy 轴表示每篇文章的引用次数。如果将这些文章按照引用次数降序排序并在直方图上进行表示,那么直方图上的最大的正方形的边长 hh 就是我们所要求的 hh。

public int hIndex(int[] citations) {
int n = citations.length;
Arrays.sort(citations);
int res = 0;
while (res < n && citations[n - 1 - res] >= res + 1) res += 1;
return res;
}
解法二:计数
不难发现,如果引用数量大于发表的论文数目,将之降到论文数是不会影响最后的结果的。这样,我们就可以通过计数排序将整个算法的时间复杂度降到O(n)。
public int hIndex(int[] citations) {
int n = citations.length;
int[] nums = new int[n + 1];
for (int cit : citations) {
nums[Math.min(cit, n)]++;
}
int res = 0;
for (int i = n - 1; i >= 0; i--) {
nums[i] = nums[i] + nums[i + 1];
}
for (int i = 0; i <= n; i++) {
if (i <= nums[i]) res = Math.max(res, i);
}
return res;
}
- 275. H-Index II
问题描述:

问题求解:
本题是一个follow up问题,由于已经进行了排序,所以可以使用O(n)遍历一遍就可以得到结果。当然由于lc的测试数据不够强大,单纯的O(n)的解法也可以过。
但是其实本质上来说,本题还是要求去找一个对数时间的算法。
public int hIndex(int[] citations) {
int n = citations.length;
if (citations.length == 0 || citations[n - 1] < 1) return 0;
// 寻找一个citations[idx] >= n - 1 - idx 最大的idx
// [l, r)
int l = 0;
int r = citations.length;
while (r - l > 1) {
int mid = l + (r - l) / 2;
if (citations[n - 1 - mid] >= mid + 1) l = mid;
else r = mid;
}
return l + 1;
}

浙公网安备 33010602011771号