LeetCode274- H 指数 | 算法练习系列

132 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第20天,点击查看活动详情

前言

今天这道题目说简单也简单,说难也难,简单在并没有复杂的算法,难在题目真的很难看懂,我甚至有那么一刹那觉得题目是有问题的,下面来看看题目吧。

题目描述

给你一个整数数组 citations ,其中 citations[i] 表示研究者的第 i 篇论文被引用的次数。计算并返回该研究者的 h 指数。

根据维基百科上 h 指数的定义:h 代表“高引用次数”,一名科研人员的 h指数是指他(她)的 (n 篇论文中)总共有 h 篇论文分别被引用了至少 h 次。且其余的 n - h 篇论文每篇被引用次数 不超过 h 次。

如果 h 有多种可能的值,h 指数 是其中最大的那个。

 

示例 1:

输入:citations = [3,0,6,1,5]

输出:3

解释:给定数组表示研究者总共有 5 篇论文,每篇论文相应的被引用了 3, 0, 6, 1, 5 次。   由于研究者有 3 篇论文每篇 至少 被引用了 3 次,其余两篇论文每篇被引用 不多于 3 次,所以她的 h 指数是 3。

示例 2:

输入:citations = [1,3,1]

输出:1

解题思路

这一题是要找h指数,那弄清楚到底什么是h指数就非常重要了,主要步骤如下:

  • 首先要明确h指数是什么,h指数指的是目标数组中有h个大于等于当前项的情况是,这个当前项就是h指数
  • 由于数组中可能存在多个h指数,题目也说了,要最大的那个
  • 首先我们把数组进行升序排序,然后从后往前开始遍历,碰到citations[i]>h的情况,就h++ 代码如下:
/**
 * @param {number[]} citations
 * @return {number}
 */
var hIndex = function (citations) {
    citations.sort((a, b) => a - b)
    var h =0 
    for(let i=citations.length-1;i>=0;i--){
        if(citations[i]>h){
            h++
        }else{
            return h
        }
    }
    return h
};

运行结果如下图:

image.png

优化

此题还可以通过使用计数排序的方式来处理,如下代码

/**
 * @param {number[]} citations
 * @return {number}
 */
var hIndex = function (citations) {
            let result = 0
            let barrels = new Array(citations.length + 1).fill(0) //这里加1的原因是为了满足中间数组的最后一项的下标和最大值相等
            for (let i = 0; i < citations.length; i++) {
                if(citations[i]>=citations.length){//这里的意思是如果当前项大于总长度,那一定不符合要求,直接放在最后一个位置即可
                    barrels[citations.length]++
                }else{
                    barrels[citations[i]]++
                }
                
            }

            let newIndex = 0
            for (let j = barrels.length - 1; j >= 0; j--) {
                result += barrels[j]
                if (result >= j) {
                    return j
                }
            }
        };

结果如下:

image.png

总结

使用技术排序的方法执行时间和内存消耗都得到了一定的提升,就是技术排序有点不好理解。第一时间不容易想到这种办法。