LeetCode #275 Medium

H-Index II

H-Index II is LeetCode 275 (Medium). You get an integer array citations, where citations[i] is how many times a researcher's i-th paper has been cited. The array is sorted in ascending order.

Return the researcher's h-index: the largest number h such that the researcher has at least h papers with h or more citations each.

  • The only difference from H-Index (LeetCode 274) is that the input arrives sorted.
  • Your algorithm must run in logarithmic time, so a single pass over the array is not enough.
Constraints
  • n == citations.length
  • 1 <= n <= 10⁵
  • 0 <= citations[i] <= 1000
  • citations is sorted in ascending order.
binary-searcharrays
Open on LeetCode ↗
02

Intuition

Because the array is sorted, one index tells you a lot. The n - i papers from index i to the end each have at least citations[i] citations, so index i proves an h-index of n - i exactly when citations[i] >= n - i.

As i moves right, citations[i] can only grow and n - i only shrinks. Once the test is true it stays true, so the indices split into a false block followed by a true block. Binary search finds that split in O(log n), and the first true index gives the most papers that clear the bar.

How to spot this pattern

A sorted array, a logarithmic time limit, and a yes/no test whose answer flips once from no to yes: that is binary search on the boundary, not on a value. Write the test as a function of the index (citations[i] >= n - i), check that it is monotonic, and search for the first index where it holds. Koko Eating Bananas and First Bad Version use the same shape.

03

Approach

Try it first

Before reading on: for citations = [0, 1, 3, 5, 6], write n - i under each value. Where does the citation count first reach that number? Then decide what your search should return when no index ever reaches it.

1

Turn the definition into a test on one index

With the array sorted, the n - i papers from index i onward all have at least citations[i] citations. So citations[i] >= n - i means "an h-index of n - i is achievable".

2

Check the test is monotonic

Moving right, citations rise and n - i falls, so once the test passes it passes for every later index. The indices form a false block and then a true block.

3

Binary search for the first passing index

Keep left = 0, right = n - 1. At each mid:

  • if citations[mid] >= n - mid, mid passes: the first pass is at mid or to its left, so set right = mid - 1;
  • otherwise it fails, and so does everything to its left: set left = mid + 1.

When the loop ends, left is the first passing index, or n if none passes.

4

Return the paper count

The answer is n - left: the number of papers from the first passing index to the end. When left = n this is 0, so an array of zeros needs no special branch.

04

H-Index II solution in Python | C++ | Java

▶1class Solution:
▶2 def hIndex(self, citations: List[int]) -> int:
▶3 n = len(citations)
▶4 left, right = 0, n - 1
▶5 while left <= right:
▶6 mid = (left + right) // 2
▶7 if citations[mid] >= n - mid:
▶8 right = mid - 1
▶9 else:
▶10 left = mid + 1
▶11 return n - left
citationspapers from i to the endcitations01356n − i54321pointersindex0L1234Rsearch [0, 4] for the first pass
n5papers
range[0, 4]first passing index is in here, or none
Each dashed step shows n − i, how many papers run from index i to the end. Since the array is sorted, all of them have at least citations[i] citations, so a bar that reaches its step proves an h-index of n − i. Bars rise and steps fall, so once a bar reaches its step every later one does too. We search for the first.
citationspapers from i to the endcitations01356n − i54321pointersindex0L12M34Rprobe mid = 2: is 3 ≥ 3?
mid2middle of [0, 4]
citations[mid]3bar height
n − mid3papers from mid onward
Probe index 2. Its step asks for 3 citations, because 3 papers start here. The target moves with mid, so it is recomputed on every probe rather than fixed in advance.
citationspapers from i to the endcitations01356n − i54321pointersindex0L1R2343 ≥ 3 passes → R = 1
test3 ≥ 3passes
best so farh ≥ 3range now [0, 1]
The bar reaches its step: 3 papers have at least 3 ≥ 3 citations, so h is at least 3. Every index to its right passes too (green). A smaller passing index would prove a larger h, so keep looking left.
citationspapers from i to the endcitations01356n − i54321pointersindex0L M1R234probe mid = 0: is 0 ≥ 5?
mid0middle of [0, 1]
citations[mid]0bar height
n − mid5papers from mid onward
Probe index 0. Its step asks for 5 citations, because 5 papers start here. The target moves with mid, so it is recomputed on every probe rather than fixed in advance.
citationspapers from i to the endcitations01356n − i54321pointersindex01L R2340 < 5 fails → L = 1
test0 < 5fails
range[1, 1]first pass is right of 0
The bar falls short: only 0 citations where 5 are needed. Everything to its left has shorter bars and taller steps, so it fails too (orange). The first passing index must be to the right.
citationspapers from i to the endcitations01356n − i54321pointersindex01L M R234probe mid = 1: is 1 ≥ 4?
mid1middle of [1, 1]
citations[mid]1bar height
n − mid4papers from mid onward
Probe index 1. Its step asks for 4 citations, because 4 papers start here. The target moves with mid, so it is recomputed on every probe rather than fixed in advance.
citationspapers from i to the endcitations01356n − i54321pointersindex01R2L341 < 4 fails → L = 2
test1 < 4fails
rangeemptyfirst pass is right of 1
The bar falls short: only 1 citation where 4 are needed. Everything to its left has shorter bars and taller steps, so it fails too (orange). The first passing index must be to the right.
3 papers with ≥ 3 citationscitations01356n − i54321pointersindex012L34return n − left = 5 − 2 = 3
left2first passing index
h-index3papers from left to the end
h = 3. The loop ends with left = 2, the first bar that reaches its step. The papers from there to the end are the 3 that each have at least 3 citations, and no earlier index can do better. Found in 3 probes, not 5 checks.
05

Common pitfalls

Returning the citation count instead of the paper count

✗ Wrong
return citations[left]
✓ Right
return n - left

The h-index counts papers. For [0, 4, 4, 4] the first passing index is 1, so three papers have at least 3 citations and the answer is 3, but citations[1] is 4. It also reads past the end when left = n.

Using > where the definition says at least

✗ Wrong
if citations[mid] > n - mid:
✓ Right
if citations[mid] >= n - mid:

"h papers with at least h citations" includes equality. On [1, 2, 100] the strict test rejects index 1 (2 papers, 2 citations) and returns 1 instead of 2.

Lower-bound template with right = n - 1

✗ Wrong
left, right = 0, n - 1
while left < right:
    mid = (left + right) // 2
    if citations[mid] >= n - mid:
        right = mid
    else:
        left = mid + 1
✓ Right
left, right = 0, n
while left < right:
    ...  # same body

In the half-open template left can never move past right, so it cannot reach n, the "no index passes" result. For [0] it stops at 0 and returns 1 instead of 0. Start right at n, or use the closed left <= right loop above.

06

Edge cases

Citations far larger than n

For [1, 2, 100] the paper with 100 citations still counts as one paper. The h-index can never exceed n, and the n - i side of the test caps it automatically: index 0 passing gives exactly n.

07

Complexity

Time
O(log n)
Space
O(1)
Each probe halves the range. The h index ii python, C++ and Java versions all keep just two indices. A left-to-right scan also finds the boundary, but it is O(n) and fails the logarithmic requirement.
08

H-Index vs H-Index II

The two problems have the same definition; only the input and the time limit differ, and that changes the algorithm.

ProblemInputBest methodTime
H-Index (LeetCode 274)unsortedcount papers per citation value, capped at n, then scan downO(n)
H-Index (LeetCode 274)unsortedsort, then scan for citations[i] >= n - iO(n log n)
H-Index II (LeetCode 275)sorted ascendingbinary search for the first citations[i] >= n - iO(log n)
09

H-Index II FAQ

What is the h-index?

The largest h such that h of the papers have at least h citations each. A researcher with papers cited 6, 5, 3, 1 and 0 times has h-index 3: three papers have 3 or more citations, but there are not four papers with 4 or more.

Why is the comparison target n - mid and not a fixed value?

n - mid is the number of papers from mid to the end, and that is the h-value index mid would prove. It changes with mid, so the search looks for where two moving quantities cross rather than for a stored number. That moving target is what makes the H Index II LeetCode problem feel different from a plain binary search.

Can the answer be larger than the largest citation count?

No. If every paper has at most c citations, no set of more than c papers can each have more than c. And it can never be larger than n, the number of papers.