Given an array citations[] of size n such that citations[i] is the number of citations a researcher received for ith paper, find the H-index.
H-index(H) is the largest value such that the researcher has published at least H papers that have been cited at least H times.
'H' stands for Hirsch index as it was proposed by the J.E. Hirsch in 2005. The H-index is defined as the author-level metric that attempts to measure both the productivity and the citation impact of the publication of the scientist or the scholar.
Examples:
Input: citations[] = [5, 0, 2, 0, 2]
Output: 2
Explanation: We can see that there are at least 2 papers whose citation count is 2 or more. In this case, the papers with 5, 2, and 2 citations qualify, and since at least 2 such papers exist, the H-index is 2.Input: citations[] = [6, 0, 3, 5, 3]
Output: 3
Explanation: Here, there are at least 3 papers that have been cited 3 or more times. The papers with 6, 5, 3, and 3 citations meet this condition. Since at least 3 such papers exist, the H-index is 3.
Table of Content
[Naive Approach] Using Comparison-based Sorting - O(n × logn) Time and O(1) Space
The idea is to sort the citation counts in descending order so that the most cited papers appear first.
Then, by scanning from the highest to the lowest citation count, we find the largest index where the number of papers considered so far is less than or equal to their citation count — this value becomes the H-index.
Step by Step Approach:
- Sort the citations[] array in descending order so that papers with the highest citations come first.
- Initialize a counter idx = 0 to track how many papers meet the H-index condition.
- Iterate through the sorted array from left to right:
=> If citations[idx] > idx, it means all papers from index 0 to idx have at least (idx + 1) citations.
=> In this case, increment idx and continue checking the next paper. - Stop when either:
=> We reach the end of the array, or
=> We find a paper where citations[idx] <= idx. - The final value of idx is the H-index.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int hIndex(vector<int> &citations) {
// sort the citations in descending order
sort(citations.begin(), citations.end(), greater<int>());
int n = citations.size();
int idx = 0;
// keep incrementing idx till citations[idx] > idx
while(idx < n && citations[idx] > idx) {
idx += 1;
}
return idx;
}
int main() {
vector<int> citations = {6, 0, 3, 5, 3};
cout << hIndex(citations) << "\n";
return 0;
}
#include <stdio.h>
int compare(const void *a, const void *b) {
return (*(int *)b - *(int *)a);
}
int hIndex(int citations[], int n) {
// sort the citations in descending order
qsort(citations, n, sizeof(int), compare);
int idx = 0;
// keep incrementing idx till citations[idx] > idx
while (idx < n && citations[idx] > idx) {
idx += 1;
}
return idx;
}
int main() {
int citations[] = {6, 0, 3, 5, 3};
int n = sizeof(citations) / sizeof(citations[0]);
printf("%d\n", hIndex(citations, n));
return 0;
}
import java.util.Arrays;
class GfG {
static int hIndex(int[] citations) {
// sort the citations in descending order
Arrays.sort(citations);
int n = citations.length;
int idx = 0;
// keep incrementing idx till citations[n - 1 - idx] > idx
while (idx < n && citations[n - 1 - idx] > idx) {
idx++;
}
return idx;
}
public static void main(String[] args) {
int[] citations = {6, 0, 3, 5, 3};
System.out.println(hIndex(citations));
}
}
def hIndex(citations):
# sort the citations in descending order
citations.sort(reverse=True)
n = len(citations)
idx = 0
# keep incrementing idx till citations[idx] > idx
while idx < n and citations[idx] > idx:
idx += 1
return idx
if __name__ == '__main__':
citations = [6, 0, 3, 5, 3]
print(hIndex(citations))
using System;
using System.Linq;
class GfG {
static int HIndex(int[] citations) {
// sort the citations in descending order
Array.Sort(citations);
Array.Reverse(citations);
int n = citations.Length;
int idx = 0;
// keep incrementing idx till citations[idx] > idx
while (idx < n && citations[idx] > idx) {
idx++;
}
return idx;
}
static void Main() {
int[] citations = {6, 0, 3, 5, 3};
Console.WriteLine(HIndex(citations));
}
}
function hIndex(citations) {
// sort the citations in descending order
citations.sort((a, b) => b - a);
let n = citations.length;
let idx = 0;
// keep incrementing idx till citations[idx] > idx
while (idx < n && citations[idx] > idx) {
idx++;
}
return idx;
}
// Driver Code
const citations = [6, 0, 3, 5, 3];
console.log(hIndex(citations));
Output
3
[Expected Approach] Using Counting Sort - O(n) Time and O(n) Space
The idea is similar to Counting Sort and maintain an array of size n + 1, say freq[] to count the frequency of citations of each paper. So, freq[i] will store the number of papers having i citations. To handle the case when number of citations > n, we can simply replace them with n. This is because the value of H-Index can be at most n as we have total n papers only.
After counting the frequency of citations, start from last index n and for each index i, keep track of the count of papers having at least i citations. If at any index i, the count of papers having at least i citations becomes >= i, then we can simply return i as the H-Index. We started from the last index n because we want to maximize the H-Index.
Step by Step Approach:
- Get the number of papers → Store n = citations.size().
- Create frequency array → freq of size n + 1 to store how many papers have a specific citation count (capped at n).
- Count citation frequencies
=> If citations[i] >= n, increment freq[n] (treat as “n or more citations”).
=> Else, increment freq[citations[i]]. - Start from maximum possible H-index → Set idx = n.
- Initialize count of qualifying papers → s = freq[n] (papers with ≥ n citations).
- Reduce idx until condition met → While s < idx:
=>Decrement idx.
=> Add freq[idx] to s (include papers with exactly idx citations). - Return H-index → Once s >= idx, return idx as the H-index.
Working:
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int hIndex(vector<int> &citations) {
int n = citations.size();
vector<int> freq(n + 1);
// count the frequency of citations
for (int i = 0; i < n; i++) {
if (citations[i] >= n)
freq[n] += 1;
else
freq[citations[i]] += 1;
}
int idx = n;
// variable to keep track of the count of papers
// having at least idx citations
int s = freq[n];
while (s < idx) {
idx--;
s += freq[idx];
}
// return the largest index for which the count of
// papers with at least idx citations becomes >= idx
return idx;
}
int main() {
vector<int> citations = {6, 0, 3, 5, 3};
cout << hIndex(citations) << "\n";
return 0;
}
#include <stdio.h>
int hIndex(int* citations, int n) {
int freq[n + 1];
for(int i = 0; i <= n; i++)
freq[i] = 0;
// count the frequency of citations
for (int i = 0; i < n; i++) {
if (citations[i] >= n)
freq[n] += 1;
else
freq[citations[i]] += 1;
}
int idx = n;
// variable to keep track of the count of papers
// having at least idx citations
int s = freq[n];
while (s < idx) {
idx--;
s += freq[idx];
}
// return the largest index for which the count of
// papers with at least idx citations becomes >= idx
return idx;
}
int main() {
int citations[] = {6, 0, 3, 5, 3};
int n = sizeof(citations) / sizeof(citations[0]);
printf("%d\n", hIndex(citations, n));
return 0;
}
import java.util.Arrays;
class GfG {
static int hIndex(int[] citations) {
int n = citations.length;
int[] freq = new int[n + 1];
// Count the frequency of citations
for (int i = 0; i < n; i++) {
if (citations[i] >= n)
freq[n] += 1;
else
freq[citations[i]] += 1;
}
int idx = n;
// variable to keep track of the count of papers
// having at least idx citations
int s = freq[n];
while (s < idx) {
idx--;
s += freq[idx];
}
// return the largest index for which the count of
// papers with at least idx citations becomes >= idx
return idx;
}
public static void main(String[] args) {
int[] citations = {6, 0, 3, 5, 3};
System.out.println(hIndex(citations));
}
}
def hIndex(citations):
n = len(citations)
freq = [0] * (n + 1)
# count the frequency of citations
for citation in citations:
if citation >= n:
freq[n] += 1
else:
freq[citation] += 1
idx = n
# variable to keep track of the count of papers
# having at least idx citations
s = freq[n]
while s < idx:
idx -= 1
s += freq[idx]
# return the largest index for which the count of
# papers with at least idx citations becomes >= idx
return idx
if __name__ == '__main__':
citations = [6, 0, 3, 5, 3]
print(hIndex(citations))
using System;
using System.Linq;
class GfG {
static int hIndex(int[] citations) {
int n = citations.Length;
int[] freq = new int[n + 1];
// count the frequency of citations
foreach (var citation in citations) {
if (citation >= n)
freq[n] += 1;
else
freq[citation] += 1;
}
int idx = n;
// variable to keep track of the count of papers
// having at least idx citations
int s = freq[n];
while (s < idx) {
idx--;
s += freq[idx];
}
// return the largest index for which the count of
// papers with at least idx citations becomes >= idx
return idx;
}
static void Main() {
int[] citations = {6, 0, 3, 5, 3};
Console.WriteLine(hIndex(citations));
}
}
function hIndex(citations) {
const n = citations.length;
const freq = new Array(n + 1).fill(0);
// count the frequency of citations
for (let citation of citations) {
if (citation >= n)
freq[n] += 1;
else
freq[citation] += 1;
}
let idx = n;
// variable to keep track of the count of papers
// having at least idx citations
let s = freq[n];
while (s < idx) {
idx--;
s += freq[idx];
}
// return the largest index for which the count of
// papers with at least idx citations becomes >= idx
return idx;
}
// Driver Code
const citations = [6, 0, 3, 5, 3];
console.log(hIndex(citations));
Output
3