Leetcode[274, 275] H-Index

###Task1 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.”

For example, given citations = [3, 0, 6, 1, 5], which 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, his h-index is 3.

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

Hint:

An easy approach is to sort the array first.
What are the possible values of h-index?
A faster approach is to use extra space.

###Python ####O(n2)

class Solution(object):
    def hIndex(self, citations):
        """
        :type citations: List[int]
        :rtype: int
        """
        if not citations:
            return 0
        N = len(citations)
        ret = len(citations)
        while ret > 0:
            count = 0
            for cite in citations:
                if cite >= ret:
                    count += 1
            if count >= ret:
                return ret
            ret -= 1
        return 0

####Bucket Sort O(n)

class Solution(object):
    def hIndex(self, citations):
        """
        :type citations: List[int]
        :rtype: int
        """
        if not citations:
            return 0
        N = len(citations)
        bucket = [0 for i in range(N + 2)]
        for cite in citations:
            if cite > N:
                bucket[-1] += 1
            else:
                bucket[cite] += 1
        count = bucket[-1]
        for i in reversed(range(N + 1)):
            count += bucket[i]
            if count >= i:
                return i
        return 0

###Java

public class Solution {
    
    public int hIndex(int[] citations) {
        if (citations == null || citations.length == 0) {
            return 0;
        }
        int len = citations.length;
        int[] buckets = new int[len + 1];
        for (int i = 0; i < len; i++) {
            if (citations[i] > len) {
                buckets[len]++;
            } else {
                buckets[citations[i]]++;
            }
        }
        int nums = 0;
        for (int i = len; i >= 0; i--) {
            nums += buckets[i];
            if (nums >= i) {
                return i;
            }
        }
        
        return 0;
    }
}

###Points

###Task2 Follow up for H-Index: What if the citations array is sorted in ascending order? Could you optimize your algorithm?

Hint:

Expected runtime complexity is in O(log n) and the input is sorted.

###Java

public class Solution {
    
    public int hIndex(int[] citations) {
        if (citations == null || citations.length == 0) {
            return 0;
        }
        int len = citations.length;
        int left = 0;
        int right = len - 1;
        while (left + 1< right) {
            int mid = left + (right - left) / 2;
            if (len - mid == citations[mid]) {
                return len - mid;
            } else if (len - mid > citations[mid]) {
                left = mid;
            } else {
                right = mid;
            }
        }
        
        if (citations[left] >= len - left) {
            return len - left;
        } else if (citations[right] >= len - right) {
            return len - right;
        }
        
        return 0;
    }
}

###Python

class Solution(object):
    def hIndex(self, citations):
        """
        :type citations: List[int]
        :rtype: int
        """
        if not citations:
            return 0
        N = len(citations)
        left = 0
        right = N - 1
        while left + 1 < right:
            mid = left + (right - left) / 2
            if N - mid == citations[mid]:
                return N - mid
            elif N - mid > citations[mid]:
                left = mid
            else:
                right = mid
        if citations[left] >= N - left:
            return N - left
        elif citations[right] >= N - right:
            return N - right

        return 0

###Points