class Solution {
public:
int hIndex(vector<int>& citations) {
if(citations.empty()) return 0;
int n = citations.size();
int h= 0;
sort(citations.begin(),citations.end());
for(int i=0;i<n;i++){//遍历数组每一个,进行比较,大于等于num[i]的个数=n-i, 因此需要满足num[i]>=n-i才行
if(citations[i]>=n-i) {
if(n-i>h) h=n-i;
}
}
return h;
}
};
先排个序,从小到大,数组中是升序的了,对于索引i的数字,后面数字都大于等于i,也就是索引i~n-1之间的数字都大于等于citations[i],如果citations[i]>=n-1-(i)+1,也就是citations[i]>=n-i,这个时候就满足至少有n-i篇论文引用数都大于等于n-i,那么遍历全局,找到最大的n-i即可。
二分查找的方法:
class Solution {
public:
int hIndex(vector<int>& citations) {
if(citations.empty()) return 0;
int n = citations.size();
int h= 0;
int left = 0,right=n-1;
while(left<=right){
int pivot = (left+right)/2;//中间下标
if(citations[pivot]==n-pivot) return n-pivot;
else if(citations[pivot]<n-pivot) left=pivot+1;
else right = pivot-1;
}
return n-left;
}
};
二分查找,我们的目标是找到citations[i]>=n-i 的最大数,其实left=0,right=n-1,循环条件是left<=right,取中间位置,判断:
(1)citations[pivot]=n-pivot,找到目标,返回n-pivot;
(2)citations[pivot]小于n-pivot,说明当前的引用次数citations[pivot]还是小,所以在右半部分找,更新左坐标=pivot+1;
(3)citations[pivot]大于n-pivot,说明当前的引用次数是够大的,但是n-pivot不一定是最优的,所以在左半部分找,更新右边界=pivot-1。
跳出循环,是说我们没有找到citations[pivot]=n-pivot,那么就是满足citations[i]>n-i 的最小的那个i,n-i才是最大,返回n-left。