【Classic 150 刷题计划】 LeetCode 274. H 指数 | C++ 二分答案法 (单调性降维打击)

LeetCode 274. H 指数

📌 题目描述

题目级别:中等

给你一个整数数组 citations ,其中 citations[i] 表示研究者的第 i 篇论文被引用的次数。计算并返回该研究者的 h 指数 。

h 指数定义 :一名科研人员的 h 指数是指他(她)至少发表了 h 篇论文,并且 至少 有 h 篇论文被引用次数大于等于 h 。如果 h 有多种可能的值,h 指数 是其中最大的那个。

  • 示例 1:
    输入:citations = [3,0,6,1,5]
    输出:3
    解释:给定数组表示研究者总共有 5 篇论文,每篇论文相应的被引用了 3, 0, 6, 1, 5 次。由于研究者有 3 篇论文每篇 至少 被引用了 3 次,所以她的 h 指数是 3。

这道题除了常规的排序法以外,有一种极具"极客思维"的解法:二分答案。

为什么可以用二分?

因为 H 指数的成立条件具有绝对的单调性 。

假设我们在测试 H 指数是否能为 x:

  • 如果满足条件(有 ≥x\ge x≥x 篇文章引用数 ≥x\ge x≥x),说明答案至少 是 x,可能更大。
  • 如果不满足条件,说明答案必然小于 x。

算法流程:

  1. 观察题目给定的数据范围,引用次数 citations[i] <= 1000,且论文总数 N≤5000N \le 5000N≤5000。这意味着 H 指数最大不可能超过 1000。
  2. 我们定义搜索区间为 [0, 1000]。
  3. 每次取中间值 mid,遍历一次数组(check 函数),统计引用数 ≥mid\ge mid≥mid 的论文数量。
  4. 如果满足要求,则收缩左边界 l = mid;如果不满足,收缩右边界 r = mid - 1。
  5. 最终 l 停下的位置,就是能满足条件的最大 H 指数。

⚠️ 极客细节避坑:

当我们在二分查找中写下 l = mid 时,计算 mid 的公式必须是向上取整的 mid = (l + r + 1) / 2。如果不加 1,当 l 和 r 只差 1 时,mid 会向下取整等于 l,导致区间无法缩小,从而陷入死循环。


💻 C++ 代码实现 (原汁原味作者版)

cpp 复制代码
class Solution {
public:
    int hIndex(vector<int>& citations) {
        // 根据题目数据范围,H指数的最大值不可能超过 1000
        int l = 0, r = 1000;

        // 二分查找寻找最大的可行解
        while (l < r)
        {
            // 向上取整,配合 l = mid 避免死循环
            int mid = (l + r + 1) / 2;

            // 如果当前的 mid 满足 H 指数条件,说明答案在 [mid, r]
            if (check(citations, mid)) l = mid;
            // 否则说明 mid 太大了,答案在 [l, mid - 1]
            else r = mid - 1;
        }

        return l;
    }

    // 辅助函数:验证是否有至少 x 篇论文的引用量 >= x
    // 💡 工程小贴士:在实际工业代码中,这里建议修改为 const vector<int>& citations
    // 以避免每次调用 check 时产生高昂的数组拷贝开销
    bool check(vector<int> citations, int x)
    {
        int cnt = 0;
        for (int i = 0; i < citations.size(); i ++ )
        {
            if (citations[i] >= x) cnt ++ ;       
        }

        return cnt >= x;
    }
};
相关推荐
春弦_15 小时前
自用算法整理二
数据结构·算法·图论
hetao173383716 小时前
2026-10-22~23 hetao1733837 的刷题记录
c++·算法
java_nnnn16 小时前
LeetCode刷题滑动窗口(串联所有单词的子串+最小覆盖的子串)Java
算法·leetcode·职场和发展
王老师青少年编程17 小时前
2025年6月GESP真题及题解(C++三级): 选择题和判断题(题解)
c++·真题·gesp·答案·csp·三级·信奥赛
Navigator_Z17 小时前
LeetCode //C - 1301. Number of Paths with Max Score
c语言·算法·leetcode
卡卡~~18 小时前
“101计划”核心课程实践教材《数据实验结构指导-C++语言版》题目集
开发语言·c++·学习·算法
企业数字化笔记18 小时前
AI视频增强后画质怎么验收?插值基线、伪细节与帧间闪烁的检查方法
人工智能·算法·音视频
学逆向的19 小时前
C 内存属性
c语言·开发语言·算法·网络安全
lengxuenong19 小时前
树状数组 · 信息学学习手册1-求和3个模板
c++·学习·算法·青少年编程