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."
For example, given citations = [3, 0, 6, 1, 5]
, which means the researcher has 5
papers
in total and each of them had received 3, 0, 6, 1, 5
citations respectively. Since the
researcher has 3
papers with at least 3
citations
each and the remaining two with no more than 3
citations
each, his h-index is 3
.
Note: If there are several possible values for h
,
the maximum one is taken as the h-index.
算法一,排序
hIndex定義爲,有h篇文章,每篇被引用的次數至少爲h;且求一個h的最大值。則爲hIndex。
爲了方便比較,此處進行的是降序排列。
class Solution {
public:
int hIndex(vector<int>& citations) {
sort(citations.rbegin(), citations.rend());
int index = 0;
while (index < citations.size() && citations[index] > index)
++index;
return index;
}
};
算法二,O(n)
算法一,需要進行排序,所以時間複雜度爲O(nlogn)。
hIndex的取值範圍爲 [0, citataions.size()]。
引入額外存儲空間,count[i], 下標表示文章的引用次數,數組元素值爲達到該引用次數的文章數量。
1. 第一趟掃描完成count數組的統計
2. 第二趟從後向前掃描count數組,並從後向前進行累加,以得出引用次數超過 i 值的文章數量,如果文章數量>= i,則滿足hIndex定義。
class Solution {
public:
int hIndex(vector<int>& citations) {
const int M = citations.size();
vector<int> count(M+2);
for (auto c: citations)
++count[c>M ? M : c];
for (int i=M; i>=0; i--) {
count[i] += count[i+1];
if (count[i] >= i)
return i;
}
return 0;
}
};
算法三,分區
使用快速排序的劃分方法。
1. 選取一個樞軸,將小於樞柚的值聚合到左邊,大於等於其值聚合到右邊。
2. 如果右區間寬度小於或者等於樞軸,則說明hIndex值至少是右區間寬度。
此時,繼續在左區間進行再次劃分,以尋找最大的hIndex值
3. 如果右區間寬度>樞軸,則不滿足hIndex定義。在右區間繼續進行劃分。
4. 直到區間爲空。
leetcode上實際執行時間爲4ms。
class Solution {
public:
int hIndex(vector<int>& citations) {
const int M = citations.size();
int hindex = 0;
int start = 0, stop = M-1;
while (start <= stop) {
auto pivot = partition(citations, start, stop);
if (M - pivot <= citations[pivot]) {
hindex = M - pivot;
stop = pivot - 1;
}
else
start = pivot + 1;
}
return hindex;
}
int partition(vector<int>& citations, int start, int stop) {
const auto pivot = citations[stop];
for (auto i=start; i<stop; i++) {
if (citations[i] < pivot)
swap(citations[i], citations[start++]);
}
swap(citations[start], citations[stop]);
return start;
}
};