力扣:275. H 指数 II

本文介绍了一种利用二分查找算法在O(logn)时间内解决LeetCode上的H指数问题的方法。H指数是指在一个不降序排列的引用序列中,至少有h个元素不小于h。通过不断调整二分查找的边界,找到满足条件的最大h值。代码中特别处理了数组只有一个元素和所有元素为0的特殊情况。

题目来源:https://leetcode-cn.com/problems/h-index-ii/

大致题意:
给定一个不降数组序列,在O(logn)的时间内找出最大的h指数,即序列中至少有h个元素不小于h。

思路

二分查找

因为是不降的数组序列,那么可以二分查找数组元素。对于当前的每个查找元素来说,有:

  1. 如果当前元素值 小于 从当前位置到数组末的元素个数和,那么当前元素显然不满足h指数的条件。同样,当前位置左边的元素同样不满足条件(数值更小,但从当前位置到数组末的元素个数和更大)。于是,二分查找右侧。
  2. 如果当前元素值 大于等于 从当前位置到数组末的元素个数和,那么当前元素显然满足h指数条件。同样,当前位置右侧也满足条件。但是,要找的是最大的h指数,数组也为非降序列,即当前位置左侧可能有值相同的数。于是,二分查找左侧。
  3. 重复以上过程,直至左右侧索引相同。

这样就保证在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;
    }
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

三更鬼

谢谢老板!

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

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

打赏作者

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

抵扣说明:

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

余额充值