LeetCode #275 H-Index II
Question
Given an array of citations sorted in ascending order (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."
Example:
Input:citations = [0,1,3,5,6]Output: 3 Explanation:[0,1,3,5,6]means the researcher has5papers in total and each of them had received 0, 1, 3, 5, 6citations respectively. Since the researcher has3papers with at least3citations each and the remaining two with no more than3citations each, her h-index is3.
Note:
If there are several possible values for h, the maximum one is taken as the h-index.
二分查找O(logn)
这题表面上是承接了H-index的一道题,实际上是一道典型的Binary Search题。
当citations排好序之后,直接找出citations[i] < i的位置即可。由于这里上升序排序,所以实际写的时候和降序稍有不同。
但此题的关键不是想到用Binary Search,而是处理Binary Search那些复杂的细节。这里介绍C++标准库<algorithm>里的超简洁、bug free的通用写法:
def lower_bound(array, first, last, value): # 返回[first, last)内第一个不小于value的值的位置 while first < last: # 搜索区间[first, last)不为空 mid = first + (last - first) // 2 # 防溢出 if array[mid] < value: first = mid + 1 else: last = mid
return first # last也行,因为[first, last)为空的时候它们重合
这样写的好处很多:
1. 简洁好记,只有first = mid+1 处用到了位置调整
2. 即使区间为空、答案不存在、有重复元素、搜索开/闭的上/下界也同样适用,鲁棒性高
要点:
1. 搜索区间是左闭右开,[first, last)
2. 只有first = mid + 1,而last = mid (这能避免死循环,详见参考资料)
3. mid = first + (last - first) // 2 (防溢出,适用于指针、迭代器,当然python大数可以不用考虑溢出)
最后将这个方法应用在本题中:
class Solution: def hIndex(self, citations: List[int]) -> int: length = len(citations) left = 0 right = length while left < right: mid = left + (right - left) // 2 if citations[mid] < length - mid: left = mid + 1 else: right = mid return length - left
非常简洁
python中其实也有二分查找的实现 bisect,见参考资料
参考:

浙公网安备 33010602011771号