二分查找题目:H 指数 II

题目

标题和出处

标题:H 指数 II

出处:275. H 指数 II

难度

5 级

题目描述

要求

给定一个整数数组 citations \texttt{citations} citations,其中 citations[i] \texttt{citations[i]} citations[i] 表示研究者的第 i \texttt{i} i 篇论文被引用的次数, citations \texttt{citations} citations 按照升序排序,计算并返回该研究者的 h 指数。

根据 h 指数的定义,一名科研人员的 h 指数是指其发表的 n \texttt{n} n 篇论文中总共有 h \texttt{h} h 篇论文分别被引用了至少 h \texttt{h} h 次,且其余的 n − h \texttt{n} - \texttt{h} nh 篇论文每篇被引用次数不超过 h \texttt{h} h 次。

如果 h \texttt{h} h 有多种可能的值,其中最大的值作为 h 指数。

请使用对数时间复杂度的算法解决此问题。

示例

示例 1:

输入: citations   =   [0,1,3,5,6] \texttt{citations = [0,1,3,5,6]} citations = [0,1,3,5,6]
输出: 3 \texttt{3} 3
解释: [0,1,3,5,6] \texttt{[0,1,3,5,6]} [0,1,3,5,6] 表示研究者总共有 5 \texttt{5} 5 篇论文,每篇论文相应的被引用了 0,   1,   3,   5,   6 \texttt{0, 1, 3, 5, 6} 0, 1, 3, 5, 6 次。
由于研究者有 3 \texttt{3} 3 篇论文每篇至少被引用了 3 \texttt{3} 3 次,其余 2 \texttt{2} 2 篇论文每篇被引用不多于 3 \texttt{3} 3 次,所以 h 指数是 3 \texttt{3} 3

示例 2:

输入: citations   =   [1,2,100] \texttt{citations = [1,2,100]} citations = [1,2,100]
输出: 2 \texttt{2} 2

数据范围

  • n = citations.length \texttt{n} = \texttt{citations.length} n=citations.length
  • 1 ≤ n ≤ 10 5 \texttt{1} \le \texttt{n} \le \texttt{10}^\texttt{5} 1n105
  • 0 ≤ citations[i] ≤ 1000 \texttt{0} \le \texttt{citations[i]} \le \texttt{1000} 0citations[i]1000
  • citations \texttt{citations} citations 按照升序排序

解法

思路和算法

这道题是「H 指数」的延伸,数组 citations \textit{citations} citations 已经按照升序排序。利用数组有序的特点,可以使用二分查找计算 h 指数,时间复杂度是 O ( log ⁡ n ) O(\log n) O(logn),其中 n n n 是论文总数。

根据 h 指数的定义可知,在升序数组 citations \textit{citations} citations 中,对于 0 ≤ x ≤ n 0 \le x \le n 0xn,被引用次数不少于 citations [ x ] \textit{citations}[x] citations[x] 的论文数量为 n − x n - x nx,这里假设 citations [ n ] = + ∞ \textit{citations}[n] = +\infty citations[n]=+。寻找符合 citations [ x ] ≥ n − x \textit{citations}[x] \ge n - x citations[x]nx 的最小的 x x x,则 n − x n - x nx 即为 h 指数。

由于 citations [ x ] \textit{citations}[x] citations[x] n − x n - x nx 都有关于 x x x 的单调性, citations [ x ] \textit{citations}[x] citations[x] 关于 x x x 单调递增, n − x n - x nx 关于 x x x 单调递减,因此可以使用二分查找计算最大的 x x x 的值。

low \textit{low} low high \textit{high} high 分别表示二分查找的下标范围的下界和上界,初始时 low = 0 \textit{low} = 0 low=0 high = n \textit{high} = n high=n

每次查找时,取 mid \textit{mid} mid low \textit{low} low high \textit{high} high 的平均数向下取整,执行如下操作。

  • 如果 citations [ mid ] ≥ n − mid \textit{citations}[\textit{mid}] \ge n - \textit{mid} citations[mid]nmid,则最小的 x x x 小于等于 mid \textit{mid} mid,因此在 [ low , mid ] [\textit{low}, \textit{mid}] [low,mid] 中继续寻找。

  • 如果 citations [ mid ] < n − mid \textit{citations}[\textit{mid}] < n - \textit{mid} citations[mid]<nmid,则最小的 x x x 大于 mid \textit{mid} mid,因此在 [ mid + 1 , high ] [\textit{mid} + 1, \textit{high}] [mid+1,high] 中继续寻找。

low = high \textit{low} = \textit{high} low=high 时,查找结束,此时 low \textit{low} low 即为最小的 x x x,h 指数为 n − low n - \textit{low} nlow

代码

class Solution {
    public int hIndex(int[] citations) {
        int n = citations.length;
        int low = 0, high = n;
        while (low < high) {
            int mid = low + (high - low) / 2;
            if (citations[mid] >= n - mid) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }
        return n - low;
    }
}

复杂度分析

  • 时间复杂度: O ( log ⁡ n ) O(\log n) O(logn),其中 n n n 是数组 citations \textit{citations} citations 的长度。二分查找的时间复杂度是 O ( log ⁡ n ) O(\log n) O(logn)

  • 空间复杂度: O ( 1 ) O(1) O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伟大的车尔尼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值