Leetcode题目解析:274. H 指数
一 摘要
H指数问题感觉是leetcode中比较冷门的一道题目,至少在过去笔试面试的经历中都没有遇到过。不过仔细看了一下,重点在于对题目的理解,同时感觉也算是相对比较简单一点的中等难度题目。本系列文章会标明引用leetcode解析的部分内容,重点在于整理和阐述分析过程。
二 题目描述
引用leetcode的描述原文如下:
三 题目解析
3.1 示例
3.2 分析
3.2.1 输入和输出
关于h的定义,题目中已经说的比较清楚。输入是一个整数数组,输出是数组对应的h值,这个值是唯一的。因为要的是“h的多种可能的值中,最大的一个”。
3.2.2 计算方法分析
看到要计算的目标,是“最大”的一个,比较容易想到的是排序、贪心、动态规划等算法。而输入本身是一维整数数组,我们先尝试用对引用次数数组排序,并初始化h为0,遍历引用次数数组来计算最大h的方法。
3.2.3 排序方法
使用的语言为Java,java.util.Arrays类中提供了对数组排序的方法,所以直接使用即可。代码及说明如下:
public class H1Solution {
public static int hIndex(int[] citations) {
// 数组升序排列
Arrays.sort(citations);
System.out.println(Arrays.toString(citations));
// 初始化i,记录当前遍历到的引用次数索引,从引用次数最大的开始
int i = citations.length - 1;
// 初始化h值为0
int h = 0;
while (i >= 0 && citations[i] > h) {
h++;
i--;
}
return h;
}
public static void main(String[] args){
int[] citations = {3,0,6,1,5};
int h = hIndex(citations);
System.out.println(h);
}
}
复杂度分析,数组长度为n:
1、时间复杂度:
2、空间复杂度:
3.2.4 计数排序
如果对上面的方法进行分析,就会发现算法的复杂度瓶颈在排序上。尽管Arrays.sort()方法我们说了“最快”,但这是指基于比较的排序,所以最好的时间复杂度才是
引用leetcode解析的描述:
从后向前遍历数组counter,对于每个 0≤i≤n,在数组counter中得到大于或等于当前引用次数 ii 的总论文数。当找到一个H 指数时跳出循环,并返回结果。
public static int hIndex(int[] citations) {
int n = citations.length, tot = 0;
int[] counter = new int[n + 1];
for (int i = 0; i < n; i++) {
if (citations[i] >= n) {
counter[n]++;
} else {
counter[citations[i]]++;
}
}
for (int i = n; i >= 0; i--) {
tot += counter[i];
if (tot >= i) {
return i;
}
}
return 0;
}