题目来源:https://leetcode-cn.com/problems/h-index-ii/
大致题意:
给定一个不降数组序列,在O(logn)的时间内找出最大的h指数,即序列中至少有h个元素不小于h。
思路
二分查找
因为是不降的数组序列,那么可以二分查找数组元素。对于当前的每个查找元素来说,有:
- 如果当前元素值 小于 从当前位置到数组末的元素个数和,那么当前元素显然不满足h指数的条件。同样,当前位置左边的元素同样不满足条件(数值更小,但从当前位置到数组末的元素个数和更大)。于是,二分查找右侧。
- 如果当前元素值 大于等于 从当前位置到数组末的元素个数和,那么当前元素显然满足h指数条件。同样,当前位置右侧也满足条件。但是,要找的是最大的h指数,数组也为非降序列,即当前位置左侧可能有值相同的数。于是,二分查找左侧。
- 重复以上过程,直至左右侧索引相同。
这样就保证在O(logn)的时间内找出最大的h指数。
不过需要注意,若数组中只有一个元素,那么需要判断该元素是否大于0,若大于则h指数为1,否则为0。
还需要注意,若数组中元素都为0,需要判断数组末尾元素是否为0,若为0,则h为0。
代码:
public int hIndex(int[] citations) {
int low = 0, high = citations.length - 1;
int h = 0;
if (high == low && citations[low] > 0) // 只有一个元素
h = 1;
else if (citations[high] == 0) // 所有元素都为0
h = 0;
else {
while (low < high) {
int mid = (low + high) / 2;
int rest = citations.length - mid; // 数组末尾至当前元素的个数和
if (citations[mid] < rest) { // 当前元素及左侧元素不满足条件
low = mid + 1;
h = rest - 1; // h指数最大为数组末尾至当前元素的个数和 - 1
}
else { // 当前元素及右侧元素满足条件
high = mid;
h = rest; // 已知的最大h指数至少为数组末尾至当前元素的个数和
}
}
}
return h;
}
本文介绍了一种利用二分查找算法在O(logn)时间内解决LeetCode上的H指数问题的方法。H指数是指在一个不降序排列的引用序列中,至少有h个元素不小于h。通过不断调整二分查找的边界,找到满足条件的最大h值。代码中特别处理了数组只有一个元素和所有元素为0的特殊情况。
546

被折叠的 条评论
为什么被折叠?



