题目
给你一个整数数组
citations,其中citations[i]表示研究者的第i篇论文被引用的次数。计算并返回该研究者的 **h指数。
题解
第一种
我们在函数中先声明一些变量,变量dp是一个空数组,用于保存排序后的引用次数,变量max是数组citations中的最大值,变量ans是一个长度为max+1的数组,初始化为0,用于统计每个引用次数的个数,我们在使用循环遍历数组citations,对于每个引用次数d,将ans数组中对应的位置的值加1,表示该引用次数出现了一次,我们在使用一个倒序的循环,从max开始遍历到0,对于每个引用次数k,将ans[k]的值减1,然后将k添加到dp数组中,这样,dp数组就保存了排序后的引用次数,从高到低排列,在将max重新赋值为0,用于记录H指数的值,我们在while循环中,判断max是否小于dp数组的长度,并且dp[max]是否大于max,如果满足则说明当前引用次数大于等于max的数量也大于等于max,将max的值加1,直到不满足条件为止,最后我们将max的值返回出去即可
var hIndex = function(citations) {
let dp=[]
let max=Math.max(...citations)
let ans=new Array(max+1).fill(0)
for(let d of citations){
ans[d]++
}
for(var k = max; k >=0; k--){
while(ans[k]-- > 0){
dp.push(k);
}
}
max=0
while(max < dp.length && dp[max] > max) max++;
return max;
};
第二种
我们这里采用二分查找进行实现,我们先声明一个isH函数,它用于计算大于等于给定引用次数mid的文章数量,在isH函数中我们先声明一个变量count用于计数,初始化为0,然后我们在使用循环遍历citations数组的每个元素,对于每个元素,如果其引用次数大于等于mid,则将count加1,最后,返回count作为结果,然后我们在函数中首先两个变量i和j,分别初始化为0和citations数组的长度,这两个变量用于表示二分查找的范围,然后使用循环进行二分查找,循环的条件是i小于等于j,在循环中,我们先计算中间位置mid,通过将i和j相加后除以2并向下取整得到,在调用isH函数来计算mid对应的H指数,isH函数接受mid和citations作为参数,返回大于等于mid的引用次数的文章数量,我们在通过比较isH函数的结果和mid来确定下一步操作,如果isH函数的结果大于mid,则说明当前mid的值过小,应将i更新为mid + 1,缩小查找范围,如果isH函数的结果小于mid,则说明当前mid的值过大,应将j更新为mid - 1,缩小查找范围,如果isH函数的结果等于mid,则找到了H指数的值,直接返回mid,当循环结束后,我们如果没有找到完全匹配的H指数值则返回j作为最终的结果即可
var hIndex = function(citations) {
let i = 0, j = citations.length;
while(i<=j){
let mid = i + Math.floor((j-i)/2);
if(isH(mid, citations) > mid){
i = mid + 1;
}else if(isH(mid, citations) < mid){
j = mid - 1;
}else{
return mid;
}
}
return j;
};
function isH(mid, citations){
let count = 0;
for(let i=0; i<citations.length; i++){
if(citations[i] >= mid){
count++;
}
}
return count
}
坚持努力,无惧未来!