一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第12天,点击查看活动详情。
题目说明
给你一个整数数组 citations ,其中 citations[i] 表示研究者的第 i 篇论文被引用的次数,citations 已经按照 升序排列 。计算并返回该研究者的 h 指数。
h 指数的定义:h 代表“高引用次数”(high citations),一名科研人员的 h 指数是指他(她)的 (n 篇论文中)总共有 h 篇论文分别被引用了至少 h 次。且其余的 n - h 篇论文每篇被引用次数 不超过 h 次。
提示:如果 h 有多种可能的值,h 指数 是其中最大的那个。
请你设计并实现对数时间复杂度的算法解决此问题。
示例 1:
输入:citations = [0,1,3,5,6] 输出:3 解释:给定数组表示研究者总共有 5 篇论文,每篇论文相应的被引用了 0, 1, 3, 5, 6 次。 由于研究者有 3 篇论文每篇 至少 被引用了 3 次,其余两篇论文每篇被引用 不多于 3 次,所以她的 h 指数是 3 。
二分查找-查找最大的h
由于数组是从小到大排好序的,所以我们要做的是:在数组中找一个最大的 h,使得后 h 个数大于等于 h,进行二分查找即可。实现如下
用二分查找算法,在数组中查找一个数,这个数的值 >= 这个数(包括)到数组最后一个数的长度(len-mid),最后返回:len-left
要返回选取的区间的长度,而选取的区间要满足区间中的数大于等于所在区间的长度。
思路:因为数组升序排列,所以比较 nums[mid]的值 和区间 [mid, len - 1] 的长度(即 len - 1 - mid + 1 = len - mid)
返回的是 nums 中的值
class Solution {
public int hIndex(int[] citations) {
int n = citations.length;
int l = 0, r = n;
while (l < r) {
int mid = l + r + 1 >>> 1;
if (citations[n - mid] >= mid) l = mid;
else r = mid - 1;
}
return r;
}
}
注意
这道题的难点在于找到一个点,这个点前后的性质不同。 所以在假设时,假设二分区间为[0, len - 1]假设一个index为下标,index之后都满足citations[index] >= len - index 这个特点。index之前都满足len - index >= citations[index]的性质。
当我们假设假设h指数为n,则citations[n-n]应>=n,如果不满足,则假设h指数为n-1,依次进行判断.直至假设h指数为1,如若不满足,肯定为0 。如果给二分再加个排序,速率会更快些哦