给你一个整数数组 citations ,其中 citations[i] 表示研究者的第 i 篇论文被引用的次数。计算并返回该研究者的 h 指数。 根据维基百科上 h 指数的定义:h 代表“高引用次数” ,一名科研人员的 h 指数 是指他(她)至少发表了 h 篇论文,并且 至少 有 h 篇论文被引用次数大于等于 h 。如果 h 有多种可能的值,h 指数 是其中最大的那个。
方法一:排序法
思路
首先对引用次数数组进行降序排序,然后从最大的可能 h
指数(即数组的长度)开始递减检查,找到满足条件(至少有 h
篇论文被引用次数大于等于 h
)的最大 h
值。
代码实现
function hIndex(citations: number[]): number {// 对引用次数数组进行降序排序citations.sort((a, b) => b - a);let h = 0;for (let i = 0; i < citations.length; i++) {if (citations[i] >= i + 1) {h = i + 1;} else {break;}}return h;
}// 示例调用
const citations = [3, 0, 6, 1, 5];
const h = hIndex(citations);
console.log("h 指数为:", h);
复杂度分析
- 时间复杂度:O(n),主要是排序操作的时间开销,常见排序算法的平均时间复杂度为 ,其中 是数组的长度。
- 空间复杂度:O(logn),这是排序算法通常需要的额外空间复杂度。
方法二:计数法
思路
先统计每个引用次数出现的论文数量,同时考虑引用次数大于等于数组长度的情况。然后从数组长度开始递减检查,累加满足条件的论文数量,找到最大的 h
值。
代码实现
function hIndex(citations: number[]): number {const n = citations.length;const count = new Array(n + 1).fill(0);// 统计每个引用次数出现的论文数量for (const citation of citations) {if (citation >= n) {count[n]++;} else {count[citation]++;}}let total = 0;// 从 n 开始递减检查for (let i = n; i >= 0; i--) {total += count[i];if (total >= i) {return i;}}return 0;
}// 示例调用
const citations2 = [3, 0, 6, 1, 5];
const h2 = hIndex(citations2);
console.log("h 指数为:", h2);
复杂度分析
- 时间复杂度:O(n),只需要遍历数组两次,第一次统计引用次数,第二次寻找
h
指数,其中 是数组的长度。 - 空间复杂度:O(n),主要用于存储计数数组。
总结
排序法实现较为直观,但时间复杂度较高;计数法时间复杂度较低,在处理大规模数据时性能更优。你可以根据实际情况选择合适的方法。