持续创作,加速成长!这是我参与「掘金日新计划 · 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
};
运行结果如下图:
优化
此题还可以通过使用计数排序的方式来处理,如下代码
/**
* @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
}
}
};
结果如下:
总结
使用技术排序的方法执行时间和内存消耗都得到了一定的提升,就是技术排序有点不好理解。第一时间不容易想到这种办法。