public int hIndex(int[] citations) {
        if (citations == null) return 0;

        int n = citations.length;
        Integer[] c = new Integer[n];
        for (int i = 0; i < n; ++i) c[i] = citations[i];
        Arrays.sort(c, Collections.reverseOrder());

        int low = 0, high = n - 1;
        // find first element that satisfies c[mid] <= mid
        while (low <= high) {
            int mid = low + (high - low) / 2;
            if (c[mid] <= mid) {
                high = mid - 1;
            } else {
                low = mid + 1;
            }
        }
        return low;
    }