题目链接
https://leetcode.com/problems/h-index-ii/
心得
274.H-Index的后续题目,假定了数组已经是有序的。按照上一篇博客的做法,对每一个可能的h值进去遍历判断,则时间复杂度为 O(n) ,不符合题设的要求 O(logn) 。看到这个时间复杂度的要求,很自然地想到二分法。
回到h的定义:在数组中找到一个数字H,使得数组中至少有H个数字大于等于H,其余的数字小于等于H。如果这个数组是有序数组,则这个定义可以进一步变成:
如果h符合定义,则
citations[len−h]≥h
,即数组中至少有H个数字大于等于H;
citations[len−h−1]≤h
,即其余的数字小于等于H。这里有一个前提条件是
len−h−1≥0
。
其中
len
是数组大小。
进一步思考,如果h不符合定义,会是什么情况:
citations[len−h]<h
:h应该更小;
citations[len−h−1]>h
:h应该更大。
有了这个公式之后,当我们判断完一个h值,我们就知道h应该往大还是往小。就可以用二分的方法来找到这个h值。
AC代码
class Solution(object):
def hIndex(self, citations):
"""
:type citations: List[int]
:rtype: int
"""
start, end = 1, len(citations)
while start <= end:
h = int((start+end)/2)
if citations[len(citations)-h] < h: # h应该更小
end = h-1
elif len(citations)-h-1>=0 and citations[len(citations)-h-1] > h: # h应该更大
start = h+1
else:
return h
return 0
if __name__ == '__main__':
s = Solution()
array = [1,1]
array.sort()
print(s.hIndex(array))
遗留问题
题目中提到:
Note: If there are several possible values for h, the maximum one is taken as the h-index.
但是用二分法的话,就有可能出现较小的h值被取得,然后程序就返回的情况。
如果避免这个问题?还是说这个问题根本不会出现?请指教。