排序题目:H 指数

题目

标题和出处

标题:H 指数

出处:274. H 指数

难度

5 级

题目描述

要求

给定一个整数数组 citations \texttt{citations} citations,其中 citations[i] \texttt{citations[i]} citations[i] 表示研究者的第 i \texttt{i} i 篇论文被引用的次数,计算并返回该研究者的 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   =   [3,0,6,1,5] \texttt{citations = [3,0,6,1,5]} citations = [3,0,6,1,5]
输出: 3 \texttt{3} 3
解释: [3,0,6,1,5] \texttt{[3,0,6,1,5]} [3,0,6,1,5] 表示研究者总共有 5 \texttt{5} 5 篇论文,每篇论文相应的被引用了 3,   0,   6,   1,   5 \texttt{3, 0, 6, 1, 5} 3, 0, 6, 1, 5 次。
由于研究者有 3 \texttt{3} 3 篇论文每篇至少被引用了 3 \texttt{3} 3 次,其余 2 \texttt{2} 2 篇论文每篇被引用不多于 3 \texttt{3} 3 次,所以 h 指数是 3 \texttt{3} 3

示例 2:

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

数据范围

  • n = citations.length \texttt{n} = \texttt{citations.length} n=citations.length
  • 1 ≤ n ≤ 5000 \texttt{1} \le \texttt{n} \le \texttt{5000} 1n5000
  • 0 ≤ citations[i] ≤ 1000 \texttt{0} \le \texttt{citations[i]} \le \texttt{1000} 0citations[i]1000

解法一

思路和算法

首先将数组 citations \textit{citations} citations 排序,然后按照从大到小的顺序遍历数组 citations \textit{citations} citations,计算 h 指数。

根据 h 指数的定义,如果已经遍历的 j j j 个元素都大于等于 j j j,则 h 指数至少为 j j j。其中最大的 j j j 的值即为 h 指数。

代码

class Solution {
    public int hIndex(int[] citations) {
        Arrays.sort(citations);
        int h = 0;
        for (int i = citations.length - 1, j = 1; i >= 0 && citations[i] >= j; i--, j++) {
            h = j;
        }
        return h;
    }
}

复杂度分析

  • 时间复杂度: O ( n log ⁡ n ) O(n \log n) O(nlogn),其中 n n n 是数组 citations \textit{citations} citations 的长度。排序需要 O ( n log ⁡ n ) O(n \log n) O(nlogn) 的时间,从大到小遍历数组需要 O ( n ) O(n) O(n) 的时间,时间复杂度是 O ( n log ⁡ n ) O(n \log n) O(nlogn)

  • 空间复杂度: O ( log ⁡ n ) O(\log n) O(logn),其中 n n n 是数组 citations \textit{citations} citations 的长度。排序需要 O ( log ⁡ n ) O(\log n) O(logn) 的递归调用栈空间。

解法二

思路和算法

解法一需要 O ( n log ⁡ n ) O(n \log n) O(nlogn) 的时间复杂度。如果使用计数代替排序,则可以降低时间复杂度。

根据 h 指数的定义,h 指数不可能超过论文总数,即如果将数组 citations \textit{citations} citations 中的大于数组长度 n n n 的元素都改成 n n n,不会改变 h 指数的结果。为了方便计算,计数时将每篇论文被引用的次数限制在范围 [ 0 , n ] [0, n] [0,n] 内,大于 n n n 的引用次数都按照 n n n 次引用计算。

得到计数之后,反向遍历计数数组,同时维护已经遍历的论文总数 sum \textit{sum} sum。当遍历到计数数组的下标 i i i 时, sum \textit{sum} sum 表示被引用至少 i i i 次的论文总数,如果 i ≥ sum i \ge \textit{sum} isum,则 i i i 就是符合要求的 h 指数值。由于 h 指数值应该取可能的最大值,因此第一个使 i ≥ sum i \ge \textit{sum} isum i i i 即为 h 指数值。

代码

class Solution {
    public int hIndex(int[] citations) {
        int n = citations.length;
        int[] counts = new int[n + 1];
        for (int citation : citations) {
            counts[Math.min(citation, n)]++;
        }
        int h = 0, sum = 0;
        for (int i = n; i >= 0; i--) {
            sum += counts[i];
            if (sum >= i) {
                h = i;
                break;
            }
        }
        return h;
    }
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组 citations \textit{citations} citations 的长度。遍历数组 citations \textit{citations} citations 计数和遍历计数数组都需要 O ( n ) O(n) O(n) 的时间。

  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组 citations \textit{citations} citations 的长度。计数需要 O ( n ) O(n) O(n) 的空间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

伟大的车尔尼

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

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

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

打赏作者

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

抵扣说明:

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

余额充值