Swift 快速解:用二分法拿下 H 指数 II,实现 O(log n) 的算法优雅突破!

在这里插入图片描述
在这里插入图片描述

摘要

在科研评价体系中,H 指数 是衡量研究者影响力的经典指标。而在算法面试中,H 指数的衍生题 H 指数 II,要求我们在 排序数组上以对数时间复杂度 解题。这不仅是一个算法挑战,更是对你二分查找理解深度的考验。

本文将带你用 Swift 实现 LeetCode 275 题的完整解法,通过二分查找优雅地求出 H 指数,并延展讲解它在实际场景中的应用,如科研平台、学术推荐系统等。

描述

你得到一个按照非降序排序的数组 citations,其中 citations[i] 表示一篇论文被引用的次数。我们要计算出该研究者的 H 指数

H 指数定义如下:

H 指数是指一个研究者至少有 h 篇论文被引用了至少 h 次,其余的论文引用数不超过 h

这道题的特别之处在于它对效率的要求——我们需要实现一个 对数时间复杂度的解法,也就是说时间复杂度应该是 O(log n)

题解答案

由于数组已经排好序,我们可以使用经典的二分查找来解决问题。二分查找的核心思路是:

  1. 从中间值开始,查看当前引用数是否满足 “剩余论文 ≥ 当前引用次数” 的条件。

  2. 如果满足,说明可能还有更高的 h 指数,在左边继续找;

  3. 如果不满足,说明当前引用数太小,向右边查找。

题解代码分析

func hIndex(_ citations: [Int]) -> Int {
    let n = citations.count
    var left = 0
    var right = n - 1

    while left <= right {
        let mid = left + (right - left) / 2
        let h = n - mid

        if citations[mid] == h {
            return h
        } else if citations[mid] < h {
            left = mid + 1
        } else {
            right = mid - 1
        }
    }

    return n - left
}

分步解析:

  • let n = citations.count:获取论文总数。

  • mid = (left + right) / 2:计算二分查找的中间位置。

  • h = n - mid:此时剩下的 n - mid 篇论文是被引用次数大于等于 citations[mid] 的论文数。

  • if citations[mid] == h:刚好符合 H 指数定义,直接返回。

  • 如果 citations[mid] < h,说明当前引用数太小,H 指数可能更大,需要向右查找。

  • 如果 citations[mid] > h,引用数太大,不满足条件,需要往左查找。

最后,当跳出循环时,left 会是第一个不满足条件的位置,H 指数为 n - left

示例测试及结果

示例 1

print(hIndex([0, 1, 3, 5, 6]))  // 输出:3

解释:3 篇论文至少被引用 3 次,符合 H 指数定义。

示例 2

print(hIndex([1, 2, 100]))  // 输出:2

解释:2 篇论文分别被引用 2 和 100 次,满足至少 2 篇被引用 ≥2 次。

示例 3

print(hIndex([0, 0, 0]))  // 输出:0

解释:没有任何论文被引用,H 指数为 0。

时间复杂度

  • 使用了 二分查找,每次查询缩小一半范围;

  • 时间复杂度:O(log n),完全满足题目要求的对数级别效率。

空间复杂度

  • 除了少量变量,算法没有额外开辟存储空间;

  • 空间复杂度:O(1)

总结

通过这道题,我们学到的不仅仅是如何计算 H 指数,更重要的是在“已排序数组”上快速查找“最大最小值边界”的二分查找技巧。

在现实应用中,类似场景还有:

  • 学术平台中对研究者影响力的定量分析;

  • 推荐算法中,基于 H 指数对内容优先级排序;

  • 甚至在新闻舆情、知识问答系统中,可以用类似机制评估信息热度。

延伸思考

  • 如果输入不是排序好的数组,如何用线性时间计算 H 指数?

  • 如果允许一定程度的引用浮动(比如 ±1),如何设计更加稳健的 H 指数计算逻辑?

  • 在并发或分布式系统中,能否做出近似的快速估算模型?

这些问题正是 H 指数在工程落地中会遇到的挑战,也是你从刷题走向工程化思维的关键一步。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

网罗开发

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值