[M二分] lc275. H 指数 II(二分答案+二分下标+二分坑点)
Posted Ypuyu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[M二分] lc275. H 指数 II(二分答案+二分下标+二分坑点)相关的知识,希望对你有一定的参考价值。
1. 题目来源
链接:275. H 指数 II
2. 题目解析
二分,有坑点。
两种思路,二分答案 h
,或者二分下标。但是二分下标有点小坑…
二分下标:
- 下标范围
0~n-1
,很自然,l=0, r=n-1
,但是当n=1
时,就根本进不去while
循环…被坑,提交后WA1
。 - 当
citations[mid] >= n - mid
时,显然就是r=mid
,因为要找最大的h
,相当于尽量往小下标找。 - 由于是二分下标,一定会停到下标的位置上
l=r
是最终停下位置,那么n-l
就是h
的数量。 - 但是,当输入是
[0]
,或者[0, 0, 0]
这样全 0 数组时,即触发无解情况时,会停到l=r=n-1
的位置,那么最终答案返回n-l=1
就是错误的,应当返回 0。 - 所以使用下标进行二分,最终需要判断答案正确性。 被坑两次,做出总结。
二分答案:
- 也可以直接针对
h
进行二分,进行坐标变换即可。 l=0, r=n
,当citations[n - mid] >= mid
时,l = mid
尽量往左找。- 这样就少了很多边界情况,方便判断了。
时间复杂度:
O
(
l
o
g
n
)
O(logn)
O(logn)
空间复杂度:
O
(
1
)
O(1)
O(1)
class Solution {
public:
int hIndex(vector<int>& citations) {
int n = citations.size();
int l = 0, r = n - 1;
while (l < r) {
int mid = l + r >> 1;
if (citations[mid] >= n - mid) r = mid;
else l = mid + 1;
}
if (citations[l] < n - l) return 0; // 二分下标,这步判断很重要
return n - l;
}
};
二分答案,没有边界情况,很舒服!
class Solution {
public:
int hIndex(vector<int>& citations) {
int n = citations.size();
int l = 0, r = n;
while (l < r) {
int mid = l + r + 1 >> 1;
if (citations[n - mid] >= mid) l = mid;
else r = mid - 1;
}
return l;
}
};
以上是关于[M二分] lc275. H 指数 II(二分答案+二分下标+二分坑点)的主要内容,如果未能解决你的问题,请参考以下文章