Follow up for H-Index: What if the citations array is sorted in ascending order? Could you optimize your algorithm?
[分析]
思路:二分查找。参考解法
[url]https://leetcode.com/discuss/56122/standard-binary-search[/url]
自己的实现倒也是二分查找,但因为没有理解二分查找的精髓,写得磕磕碰碰,修修补补才被Accept,代码因此也不好看,yb君一开始甚至以为是错误的。看讨论区高票解法时觉得不理解,为什么不用考虑我实现中需要的特殊情形呢,为什么return 那样写。yb君指点说,使用二分查找解题时要清楚左右边界代表的含义,参考解法中[left, right]表示尚待判断的区间,[0, left -1]表示已确认不属于目标集合的区间,而[right+1, N - 1]表示已确认属于目标集合的区间。
换句话说right表示不属于目标集合的最大下标。因此迭代结束,right + 1是目标集合的第一个元素。目标集合中元素的性质是citations[i] >= 目标集合大小。
[分析]
思路:二分查找。参考解法
[url]https://leetcode.com/discuss/56122/standard-binary-search[/url]
自己的实现倒也是二分查找,但因为没有理解二分查找的精髓,写得磕磕碰碰,修修补补才被Accept,代码因此也不好看,yb君一开始甚至以为是错误的。看讨论区高票解法时觉得不理解,为什么不用考虑我实现中需要的特殊情形呢,为什么return 那样写。yb君指点说,使用二分查找解题时要清楚左右边界代表的含义,参考解法中[left, right]表示尚待判断的区间,[0, left -1]表示已确认不属于目标集合的区间,而[right+1, N - 1]表示已确认属于目标集合的区间。
换句话说right表示不属于目标集合的最大下标。因此迭代结束,right + 1是目标集合的第一个元素。目标集合中元素的性质是citations[i] >= 目标集合大小。
public class Solution {
public int hIndex(int[] citations) {
if (citations == null || citations.length == 0)
return 0;
int N = citations.length;
int left = 0, right = N - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (citations[mid] == N - mid)
return citations[mid];
else if (citations[mid] > N - mid)
right = mid - 1;
else
left = mid + 1;
}
return N - (right + 1);
}
}