Given an array of citations (each citation is a non-negative integer) of a researcher, write a function to compute the researcher's h-index.
According to the definition of h-index on Wikipedia: "A scientist has index h if h of his/her N papers have at least h citations each, and the other N − h papers have no more than h citations each."
Example:
Input:citations = [3,0,6,1,5]
Output: 3 Explanation:[3,0,6,1,5]
means the researcher has5
papers in total and each of them had received3, 0, 6, 1, 5
citations respectively. Since the researcher has3
papers with at least3
citations each and the remaining two with no more than3
citations each, her h-index is3
.
Note: If there are several possible values for h, the maximum one is taken as the h-index.
思路:
这道题的解法有很多,以下提供四种作为参考:
解法1 暴力求解
我们从小到大对可能的答案进行判断:
class Solution {
public:
int hIndex(vector<int>& citations) {
int H = 0;
for (H = citations.size(); H >= 0; H--) {
if (validH(citations, H)) break;
}
return H;
}
private:
bool validH(const vector<int>& citations, int H) {
int count = 0;
for (int citation : citations) if (citation >= H) count++;
return count >= H;
}
};
解法2 二分查找
我们根据找到的符合条件的数的个数作为阈值进行二分查找:
class Solution {
public:
int hIndex(vector<int>& citations) {
int left = 0, right = citations.size();
int mid = (left+right)/2;
while (left < right) {
if (validH(citations, mid) >= mid) left = mid + 1;
else right = mid - 1;
mid = (left + right) / 2;
}
int count = validH(citations, mid);
if (count >= mid) return mid;
else return mid - 1;
}
private:
int validH(const vector<int>& citations, int H) {
int count = 0;
for (int citation : citations) if (citation >= H) count++;
return count;
}
};
解法3 排序
我们将原序列排序后,找到第一个满足条件的值:
class Solution {
public:
int hIndex(vector<int>& citations) {
sort(citations.begin(), citations.end());
int n = citations.size();
for (int i = 0; i < n; i++) {
if (citations[i] >= n - i) return n - i;
}
return 0;
}
};
解法4 桶排序
这个方法比较取巧,代码如下:
class Solution {
public:
int hIndex(vector<int>& citations) {
vector<int> record(citations.size() + 1, 0);
int n = citations.size();
for (int citation : citations) {
int id = min(citation, n);
record[id]++;
}
int count = 0;
int res;
for (int i = 0; i <= n; i++) {
if (n - count >= i) res = i;
count += record[i];
}
return res;
}
};