首先对数组升序排序,末尾即最大值 max,那么在该数组中 H 可能的最大值就是 max = Math.min(len, citations[len - 1])
从前往后遍历,在数组中查找大于等于 max 的最小位置,然后计算这样的数有多少个并与 max 进行比较
为什么是大于等于 max 呢?因为当得到的个数小于当前的 max 时,接下来需要使 max-- 继续查找,而此时 max 的值在数组中不一定存在
代码如下:
public static int hIndex(int[] citations) {
int len = citations.length;
//时间复杂度:O(n*logn);空间复杂度:O(logn)
Arrays.sort(citations);
int max = Math.min(len, citations[len - 1]), index = len - 1;
while (max > 0) {
//H 不可能待遇总的论文发表数
if (max > len) {
max = len;
continue;
}
for (int i = 0; i < len; i++) {
if (citations[i] >= max) {
index = i;
break;
}
}
if ((len - index) >= max)
return max;
max--;
index = len - 1;
}
return 0;
}
排序优化:从后往前
public static int hIndex(int[] citations) {
Arrays.sort(citations);
int h = 0, i = citations.length - 1;
while (i >= 0 && citations[i] > h) {
h++;
i--;
}
return h;
}
计数排序
前面排序方法的时间空间复杂度依赖于排序算法,考虑将其替换优化
时间复杂度:O(n) 空间复杂度:O(n)
代码如下:
public static int hIndex2(int[] citations) {
int len = citations.length, h = 0;
//新建数组 count,记录当前引用次数对应的论文篇数,count[len] 记录引用数大于等于论文数的情况
int[] count = new int[len + 1];
for (int i = 0; i < len; i++) {
if (citations[i] >= len) {
count[len]++;
} else {
count[citations[i]]++;
}
}
//从后往前查找
for (int i = len; i >= 0; i--) {
h += count[i];
if (h >= i) return i;
}
return 0;
}