zoukankan      html  css  js  c++  java
  • (Java) LeetCode 274. H-Index —— H指数

    Given an array of citations (each citation is a non-negative integer) of a researcher, write a function to compute the researcher's h-index.

    According to the definition of h-index on Wikipedia: "A scientist has index h if h of his/her N papers have at least h citations each, and the other N − h papers have no more than h citations each."

    Example:

    Input: citations = [3,0,6,1,5]
    Output: 3 
    Explanation: [3,0,6,1,5] means the researcher has 5 papers in total and each of them had 
                 received 3, 0, 6, 1, 5 citations respectively. 
                 Since the researcher has 3 papers with at least 3 citations each and the remaining 
                 two with no more than 3 citations each, her h-index is 3.

    Note: If there are several possible values for h, the maximum one is taken as the h-index.


    解法一,O(nlogn):

    上来先排序,这么做的理由显而易见,因为排过序之后就会建立引用数和文章数的关系。比如例子中,排过序之后就变成了{0, 1, 3, 5, 6}。如果倒序遍历排序过的数组就会获得如下信息:第五篇文章被引用6次,证明有五篇文章引用次数小于或等于它,换句话说就是有一篇文章引用次数大于或等于5。而H指数要求有h篇文章至少被引用h次,那么证明这个引用次数太大了,所以继续向引用次数较小的方向遍历。当遍历到第四篇文章的时候,被引用次数是5次,证明有两篇文章的引用次数大于等于5。再继续,第三篇被引用三次,那么就是有三篇文章引用次数大于等于3次。而再继续向下遍历的时候,知道有四篇文章的引用数大于等于1,已经不满足条件了。所以其实对于例子来说,H指数已经求出来了,就是3,即结果出现在介于满足和不满足定义之间的那次遍历。再想一下特殊的情况,假如输入是{3, 3, 3, 5, 6}呢?遍历到第三篇的时候得知至少有三篇文章引用次数大于等于3,而到了第二篇的时候就是4篇文章引用次数大于等于3,H指数就比定义大了。所以当文章数第一次达到临界值的时候,H指数不应该再增加了。体现在代码上就是严格的大于号,而不是大于等于号。如果想不明白,可以想一个{0, 0, 0}或{1, 1, 1}的例子。详见下文代码。

    解法二,O(n):

    解法一排序的目的就是为了建立引用数和文章数的关系。有没有办法不排序,或者至少不通过比较排序而建立这个关系呢?因为比较排序的时间复杂度至少也是线性对数级别,非比较排序是可以优化到线性时间复杂度的。这个时候就想起了计数排序。通过计数,直接统计每个引用次数下面有多少文章。而再通过扫描累加,就会知道大于等于某一个引用次数的文章是多少。当找到第一个文章数大于等于引用数的计数点,即找到了所求。这里要注意如果一篇文章的引用数大于等于总文章数,那么它对H指数的贡献最多是n次,即文章总数。因为H指数是不可能大于总文章数的。所以在计数的时候把这类文章单独放到计数数组最后面,再加上特别的判断即可。详见代码。


    解法一(Java)

    class Solution {
        public int hIndex(int[] citations) {
            if (citations == null || citations.length == 0) return 0;
            Arrays.sort(citations);
            int res = 0;
            for (int i = citations.length - 1; i >= 0; i--)
                    if (citations[i] > res) res++;
            return res;
        }
    }

    解法二(Java)

    class Solution {
        public int hIndex(int[] citations) {
            int n = citations.length;
            int[] count = new int[n + 1];
            for (int i = 0; i < n; i++) {
                if (citations[i] >= n) count[n]++; //统计引用数比总文章数还多的文章数目
                else count[citations[i]]++; //统计每个引用次数下有多少篇文章
            }
            if (count[n] >= n) return n; //如果每篇文章的引用数都比文章数多,那H指数最多也只能是文章数n
            for (int i = n - 1; i >= 0; i--) {
                count[i] += count[i + 1]; //不要忘了这里的i一直是引用次数,所以这一步在统计大于等于i的文章总数,即逐个累加大于等于i的计数
                if (count[i] >= i) return i; //一旦找到满足条件的引用次数,即返回
            }
            return 0;
        }
    }
  • 相关阅读:
    算法基础~链表~求两个链表的交点(不考虑时间、空间复杂度)
    《人月神话》阅读笔记一
    html与css学习笔记
    新手教程
    课程信息管理
    关于文件动手动脑
    四则运算随机生成
    关于异常
    第四次动手动脑
    第三次动手动脑
  • 原文地址:https://www.cnblogs.com/tengdai/p/9251855.html
Copyright © 2011-2022 走看看