[M二分] lc275. H 指数 II(二分答案+二分下标+二分坑点)

本文探讨了如何使用二分法解决H指数问题,特别强调了在二分下标过程中遇到的边界条件陷阱,并提供了两种解决方案,包括针对下标和答案的二分策略。作者分享了从实践中总结的经验教训,确保正确处理全0数组导致的无解情况。
摘要由CSDN通过智能技术生成

1. 题目来源

链接:275. H 指数 II

相关:[M排序] lc274. H 指数(排序+模拟)

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;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ypuyu

如果帮助到你,可以请作者喝水~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值