Leetcode274.H指數(shù)

題目描述:

給定一位研究者論文被引用次數(shù)的數(shù)組(被引用次數(shù)是非負(fù)整數(shù))。編寫一個方法,計算出研究者的 h 指數(shù)。
h 指數(shù)的定義: “h 代表“高引用次數(shù)”(high citations),一名科研人員的 h 指數(shù)是指他(她)的 (N 篇論文中)至多有 h 篇論文分別被引用了至少 h 次。(其余的 N - h 篇論文每篇被引用次數(shù)不多于 h 次。)”

示例:

輸入: citations = [3,0,6,1,5]
輸出: 3
解釋: 給定數(shù)組表示研究者總共有 5 篇論文,每篇論文相應(yīng)的被引用了 3, 0, 6, 1, 5 次。
由于研究者有 3 篇論文每篇至少被引用了 3 次,其余兩篇論文每篇被引用不多于 3 次,所以她的 h 指數(shù)是 3。

說明:

如果 h 有多種可能的值,h 指數(shù)是其中最大的那個。

解答思路1

對數(shù)據(jù)進(jìn)行排序,當(dāng)索引i位置的值大于N-i(即包含所處位置以及后面數(shù)據(jù)的個數(shù))時,滿足條件。

class Solution(object):
    def hIndex(self, citations):
        """
        :type citations: List[int]
        :rtype: int
        """
        count = len(citations)
        citations.sort()
        temp = float('-inf')
        for i in range(count):
            if citations[i] >= count - i:
                temp = max(temp, count - i)
        if temp != float('-inf'):
            return temp
        else:
            return 0
解答思路2(計數(shù))

源自官方解答:https://leetcode-cn.com/problems/h-index/solution/hzhi-shu-by-leetcode/

分析

基于比較的排序算法存在時間復(fù)雜度下界 O(n\log n)O(nlogn),如果要得到時間復(fù)雜度更低的算法,就必須考慮不基于比較的排序。

算法

方法一中,我們通過降序排序得到了 hh 指數(shù),然而,所有基于比較的排序算法,例如堆排序,合并排序和快速排序,都存在時間復(fù)雜度下界 O(nlogn)。要得到時間復(fù)雜度更低的算法. 可以考慮最常用的不基于比較的排序,計數(shù)排序。
然而,論文的引用次數(shù)可能會非常多,這個數(shù)值很可能會超過論文的總數(shù) nn,因此使用計數(shù)排序是非常不合算的(會超出空間限制)。在這道題中,我們可以通過一個不難發(fā)現(xiàn)的結(jié)論來讓計數(shù)排序變得有用,即:

如果一篇文章的引用次數(shù)超過論文的總數(shù) n,那么將它的引用次數(shù)降低為 n 也不會改變 h 指數(shù)的值。

由于 h 指數(shù)一定小于等于 n,因此這樣做是正確的。在直方圖中,將所有超過 y 軸值大于 n 的變?yōu)?n 等價于去掉 y>n 的整個區(qū)域。

image.png

從直方圖中可以更明顯地看出結(jié)論的正確性,將 y>n 的區(qū)域去除,并不會影響到最大的正方形,也就不會影響到 h 指數(shù)。
我們用一個例子來說明如何使用計數(shù)排序得到 h 指數(shù)。首先,引用次數(shù)如下所示:
citations=[1, 3, 2, 3, 100]
將所有大于 n=5 的引用次數(shù)變?yōu)?n,得到:
citations = [1, 3, 2, 3, 5]
計數(shù)排序得到的結(jié)果如下:

k 0 1 2 3 4 5
count 0 1 1 2 0 1
s_k 5 5 4 3 1 1

其中 s_k 表示至少有 k 次引用的論文數(shù)量,在表中即為在它之后的列(包括本身)的 count 一行的和。根據(jù)定義,最大的滿足 k ≤ s_k 的 k 即為所求的 h。在表中,這個 k 為 3,因此 h 指數(shù)為 3。

public class Solution {
    public int hIndex(int[] citations) {
        int n = citations.length;
        int[] papers = new int[n + 1];
        // 計數(shù)
        for (int c: citations)
            papers[Math.min(n, c)]++;
        // 找出最大的 k
        int k = n;
        for (int s = papers[n]; k > s; s += papers[k])
            k--;
        return k;
復(fù)雜度分析

時間復(fù)雜度:O(n)。在計數(shù)時,我們僅需要遍歷 citations 數(shù)組一次,因此時間復(fù)雜度為 O(n)。在找出最大的 k 時,我們最多需要遍歷計數(shù)的數(shù)組一次,而計數(shù)的數(shù)組的長度為 O(n),因此這一步的時間復(fù)雜度為 O(n),即總的時間復(fù)雜度為 O(n)。
空間復(fù)雜度:O(n)。我們需要使用 O(n) 的空間來存放計數(shù)的結(jié)果。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容