Given an array of integers citations
where citations[i]
is the number of citations a researcher received for their ith
paper and citations
is sorted in ascending order, return the researcher's h-index.
According to the definition of h-index on Wikipedia: The h-index is defined as the maximum value of h
such that the given researcher has published at least h
papers that have each been cited at least h
times.
You must write an algorithm that runs in logarithmic time.
Example 1:
Input: citations = [0,1,3,5,6] Output: 3 Explanation: [0,1,3,5,6] means the researcher has 5 papers in total and each of them had received 0, 1, 3, 5, 6 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, their h-index is 3.
Example 2:
Input: citations = [1,2,100] Output: 2
Constraints:
n == citations.length
1 <= n <= 105
0 <= citations[i] <= 1000
citations
is sorted in ascending order.This problem asks to find the h-index of a researcher given a sorted array of citation counts for their papers. The h-index is the largest number h such that the researcher has at least h papers with at least h citations each. Since the input array citations
is sorted in ascending order, we can leverage this property to design an efficient algorithm using binary search.
Understanding the Logic
The key observation is the monotonic nature of the problem. If a researcher has at least x
papers with at least x
citations, then it's guaranteed that they also have at least y
papers with at least y
citations for any y < x
. This allows us to efficiently search for the maximum h
using binary search.
Algorithm (Binary Search)
Initialization: Set left
to 0 and right
to the length of citations
(n). This defines the search space for the h-index.
Iteration: While left
is less than right
:
mid = (left + right + 1) // 2
(integer division). The +1
ensures we lean towards a higher mid
to find the maximum h-index.citations[n - mid] >= mid
. This checks if there are at least mid
papers with at least mid
citations.
left = mid
.mid
is too high, so we update right = mid - 1
.Result: After the loop terminates, left
holds the maximum value of h
that satisfies the condition.
Time and Space Complexity Analysis
Time Complexity: O(log n), where n is the length of the citations
array. This is because we use binary search, which reduces the search space by half in each iteration.
Space Complexity: O(1). The algorithm uses only a few constant extra variables.
Code Implementation in Multiple Languages
The following code demonstrates the solution using several popular programming languages. The core logic remains the same across all implementations.
Python3:
class Solution:
def hIndex(self, citations: List[int]) -> int:
n = len(citations)
left, right = 0, n
while left < right:
mid = (left + right + 1) // 2 # Integer division
if citations[n - mid] >= mid:
left = mid
else:
right = mid - 1
return left
Java:
class Solution {
public int hIndex(int[] citations) {
int n = citations.length;
int left = 0, right = n;
while (left < right) {
int mid = (left + right + 1) / 2; //Integer division
if (citations[n - mid] >= mid) {
left = mid;
} else {
right = mid - 1;
}
}
return left;
}
}
C++:
class Solution {
public:
int hIndex(vector<int>& citations) {
int n = citations.size();
int left = 0, right = n;
while (left < right) {
int mid = (left + right + 1) / 2; //Integer division
if (citations[n - mid] >= mid) {
left = mid;
} else {
right = mid - 1;
}
}
return left;
}
};
Go:
func hIndex(citations []int) int {
n := len(citations)
left, right := 0, n
for left < right {
mid := (left + right + 1) / 2 //Integer division
if citations[n-mid] >= mid {
left = mid
} else {
right = mid - 1
}
}
return left
}
(Other languages like TypeScript, Rust, and C# would follow a similar pattern, with minor syntax adjustments.)
This detailed explanation provides a comprehensive understanding of the problem, the algorithm, and its implementation in various programming languages, along with a clear complexity analysis.