算法题解-H指数

191 阅读3分钟

题目

给你一个整数数组 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
}

坚持努力,无惧未来!