H指數計算


H指數定義:
H指數是用來綜合衡量學者發表論文的數量和質量的指標。
若某學者共發表N篇論文,H指數是指存在h篇論文至少每篇有h引用量,剩下的N-h篇中,每篇都不超過h引用量。
H指數也可以是期刊H指數,機構H指數,學者H指數等等。
一.排序法

復雜度
時間 O(NlogN) 空間 O(1)

思路

先將數組排序,我們就可以知道對於某個引用數,有多少文獻的引用數大於這個數。對於引用數citations[i],大於該引用數文獻的數量是citations.length - i,而當前的H-Index則是Math.min(citations[i], citations.length - i),我們將這個當前的H指數和全局最大的H指數來比較,得到最大H指數。

代碼

//排序按引用次數正序排序,並且可以舍棄為0的引用減少計算。

public class Solution {
    public int hIndex(int[] citations) {
        // 排序
        Arrays.sort(citations);
        int h = 0;
        for(int i = 0; i < citations.length; i++){
            // 得到當前的H指數
            int currH = Math.min(citations[i], citations.length - i);
            if(currH > h){
                h = currH;
            }
        }
        return h;
    }
}

二.數組映射法

復雜度
時間 O(N) 空間 O(N)

思路

也可以不對數組排序,我們額外使用一個大小為N+1的數組stats。stats[i]表示有多少文章被引用了i次,這里如果一篇文章引用大於N次,我們就將其當為N次,因為H指數不會超過文章的總數。為了構建這個數組,我們需要先將整個文獻引用數組遍歷一遍,對相應的格子加一。統計完后,我們從N向1開始遍歷這個統計數組。如果遍歷到某一個引用次數時,大於或等於該引用次數的文章數量,大於引用次數本身時,我們可以認為這是H指數。之所以不用再向下找,因為我們要取最大的H指數。那如何求大於或等於某個引用次數的文章數量呢?我們可以用一個變量,從高引用次的文章數累加下來。因為我們知道,如果有x篇文章的引用大於等於3次,那引用大於等於2次的文章數量一定是x加上引用次數等於2次的文章數量。

代碼



public class Solution {
    public int hIndex(int[] citations) {
        int[] stats = new int[citations.length + 1];
        int n = citations.length;
        // 統計各個引用次數對應多少篇文章
        for(int i = 0; i < n; i++){
            stats[citations[i] <= n ? citations[i] : n] += 1;
        }
        int sum = 0;
        // 找出最大的H指數
        for(int i = n; i > 0; i--){
            // 引用大於等於i次的文章數量,等於引用大於等於i+1次的文章數量,加上引用等於i次的文章數量
            sum += stats[i];
            // 如果引用大於等於i次的文章數量,大於引用次數i,說明是H指數
            if(sum >= i){
                return i;
            }
        }
        return 0;
    }
}

三 . 二分搜索法(優化)

復雜度
時間 O(logN) 空間 O(1)

思路

在升序的引用數數組中,假設數組長為N,下標為i,則N - i就是引用次數大於等於下標為i的文獻所對應的引用次數的文章數。如果該位置的引用數小於文章數,則說明則是有效的H指數,如果一個數是H指數,那最大的H指數一定在它的后面(因為是升序的)。根據這點就可已進行二分搜索了。這里min = mid + 1的條件是citations[mid] < n - mid,確保退出循環時min肯定是指向一個有效的H指數。

代碼



public class Solution {
    public int hIndex(int[] citations) {
        int n = citations.length;
        if(n == 0) return 0;
        int min = 0, max = citations.length - 1;
        while(min <= max){
            int mid = (min + max) / 2;
            // 如果該點是有效的H指數,則最大H指數一定在右邊
            if(citations[mid] < n - mid){
                min = mid + 1;
            // 否則最大H指數在左邊
            } else {
                max = mid - 1;
            }
        }
        // n - min是min點的H指數
        return n - min;
    }
}                           
               


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM