LeetCode 274: H-Index (Sort + Threshold Scan)
LeetCode 274SortingArrayToday we solve LeetCode 274 - H-Index.
Source: https://leetcode.com/problems/h-index/
English
Problem Summary
Given an integer array citations, where citations[i] is the number of citations for paper i, return the researcher's h-index.
The h-index is the maximum h such that the researcher has at least h papers with at least h citations each.
Key Insight
After sorting citations in descending order, position i means we are checking whether there are at least i+1 papers having at least i+1 citations. If citations[i] >= i+1, then h can be at least i+1.
Brute Force and Limitations
Brute force tries every h from 0..n and counts how many papers satisfy citations >= h, leading to O(n^2) in the worst case.
Optimal Algorithm Steps
1) Sort citations in descending order.
2) Initialize h = 0.
3) Scan index i from left to right.
4) If citations[i] >= i+1, set h = i+1; otherwise stop early.
5) Return h.
Complexity Analysis
Time: O(n log n) (sorting dominates).
Space: O(1) extra in-place sort (language-dependent recursion/implementation overhead may apply).
Common Pitfalls
- Sorting ascending but using descending logic.
- Using > instead of >= for threshold check.
- Forgetting that h-index is bounded by number of papers n.
Reference Implementations (Java / Go / C++ / Python / JavaScript)
import java.util.Arrays;
class Solution {
public int hIndex(int[] citations) {
Arrays.sort(citations);
int n = citations.length;
int h = 0;
for (int i = 0; i < n; i++) {
int c = citations[n - 1 - i]; // descending view
if (c >= i + 1) {
h = i + 1;
} else {
break;
}
}
return h;
}
}import "sort"
func hIndex(citations []int) int {
sort.Ints(citations)
n := len(citations)
h := 0
for i := 0; i < n; i++ {
c := citations[n-1-i] // descending view
if c >= i+1 {
h = i + 1
} else {
break
}
}
return h
}class Solution {
public:
int hIndex(vector& citations) {
sort(citations.begin(), citations.end());
int n = (int)citations.size();
int h = 0;
for (int i = 0; i < n; ++i) {
int c = citations[n - 1 - i]; // descending view
if (c >= i + 1) {
h = i + 1;
} else {
break;
}
}
return h;
}
}; class Solution:
def hIndex(self, citations: list[int]) -> int:
citations.sort()
n = len(citations)
h = 0
for i in range(n):
c = citations[n - 1 - i] # descending view
if c >= i + 1:
h = i + 1
else:
break
return hfunction hIndex(citations) {
citations.sort((a, b) => a - b);
const n = citations.length;
let h = 0;
for (let i = 0; i < n; i++) {
const c = citations[n - 1 - i]; // descending view
if (c >= i + 1) {
h = i + 1;
} else {
break;
}
}
return h;
}中文
题目概述
给定一个整数数组 citations,其中 citations[i] 表示第 i 篇论文的引用次数,求该研究者的 h 指数。
h 指数定义为:存在最大整数 h,使得至少有 h 篇论文的引用次数都不少于 h。
核心思路
把数组按降序看待后,第 i 个位置(从 0 开始)表示“当前至少有 i+1 篇论文”,只要满足 citations[i] >= i+1,就说明 h 可以更新为 i+1。
暴力解法与不足
暴力法枚举每个可能的 h(0 到 n),每次都遍历数组统计满足 citations >= h 的论文数,最坏时间复杂度是 O(n^2)。
最优算法步骤
1)先将 citations 排序。
2)按“降序视角”从大到小检查。
3)若当前引用数 c >= i+1,更新 h = i+1。
4)一旦不满足可提前结束。
5)返回最终 h。
复杂度分析
时间复杂度:O(n log n)(排序主导)。
空间复杂度:O(1) 额外空间(具体与语言排序实现有关)。
常见陷阱
- 升序排序后却直接按降序下标逻辑写错。
- 阈值比较写成 > 而不是 >=。
- 忽略 h 指数上限不会超过论文总数 n。
参考实现(Java / Go / C++ / Python / JavaScript)
import java.util.Arrays;
class Solution {
public int hIndex(int[] citations) {
Arrays.sort(citations);
int n = citations.length;
int h = 0;
for (int i = 0; i < n; i++) {
int c = citations[n - 1 - i]; // 降序视角
if (c >= i + 1) {
h = i + 1;
} else {
break;
}
}
return h;
}
}import "sort"
func hIndex(citations []int) int {
sort.Ints(citations)
n := len(citations)
h := 0
for i := 0; i < n; i++ {
c := citations[n-1-i] // 降序视角
if c >= i+1 {
h = i + 1
} else {
break
}
}
return h
}class Solution {
public:
int hIndex(vector& citations) {
sort(citations.begin(), citations.end());
int n = (int)citations.size();
int h = 0;
for (int i = 0; i < n; ++i) {
int c = citations[n - 1 - i]; // 降序视角
if (c >= i + 1) {
h = i + 1;
} else {
break;
}
}
return h;
}
}; class Solution:
def hIndex(self, citations: list[int]) -> int:
citations.sort()
n = len(citations)
h = 0
for i in range(n):
c = citations[n - 1 - i] # 降序视角
if c >= i + 1:
h = i + 1
else:
break
return hfunction hIndex(citations) {
citations.sort((a, b) => a - b);
const n = citations.length;
let h = 0;
for (let i = 0; i < n; i++) {
const c = citations[n - 1 - i]; // 降序视角
if (c >= i + 1) {
h = i + 1;
} else {
break;
}
}
return h;
}
Comments