【leetcode面试经典150题】11.H指数(C++)

【leetcode面试经典150题】专栏系列将为准备暑期实习生以及秋招的同学们提高在面试时的经典面试算法题的思路和想法。本专栏将以一题多解和精简算法思路为主,题解使用C++语言。(若有使用其他语言的同学也可了解题解思路,本质上语法内容一致)

【题目描述】

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

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

【示例一】

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

【示例二】

复制代码
输入:citations = [1,3,1]
输出:1

【提示及数据范围】

  • n == citations.length
  • 1 <= n <= 5000
  • 0 <= citations[i] <= 1000

【代码】

cpp 复制代码
// 方法一:排序

// 初始的 H 指数 h 设为 0,然后将引用次数排序,并且对排序后的数组从大到小遍历。
// 根据 H 指数的定义,如果当前 H 指数为 h 并且在遍历过程中找到当前值 citations[i]>h ,
// 则说明我们找到了一篇被引用了至少 h+1 次的论文,所以将现有的 h 值加 1。
// 继续遍历直到 h 无法继续增大。最后返回 h 作为最终答案。

int hIndex(vector<int>& citations) {
        sort(citations.begin(), citations.end());
        int h = 0, i = citations.size() - 1;
        while (i >= 0 && citations[i] > h) {
            h++;
            i--;
        }
        return h;
}


// 方法二:计数排序

// 新建并维护一个数组 counter 用来记录当前引用次数的论文有几篇。
// 从后向前遍历数组 counter,对于每个 0 ≤ i ≤ n,
// 在数组 counter 中得到大于或等于当前引用次数 i 的总论文数。
// 当我们找到一个 H 指数时跳出循环,并返回结果。
int hIndex(vector<int>& citations) {
        int n = citations.size(), tot = 0;
        vector<int> counter(n + 1);
        for (int i = 0; i < n; i++) {
            if (citations[i] >= n) {
                counter[n]++;
            } else {
                counter[citations[i]]++;
            }
        }
        for (int i = n; i >= 0; i--) {
            tot += counter[i];
            if (tot >= i) {
                return i;
            }
        }
        return 0;
}


// 方法三:二分

// 设查找范围的初始左边界 left 为 0,初始右边界 right 为 n。
// 每次在查找范围内取中点 mid,同时扫描整个数组,判断是否至少有 mid 个数大于 mid。
// 如果有,说明要寻找的 h 在搜索区间的右边,反之则在左边。

int hIndex(vector<int>& citations) {
        int left=0,right=citations.size();
        int mid=0,cnt=0;
        while(left<right){
            // +1 防止死循环
            mid=(left+right+1)>>1;
            cnt=0;
            for(int i=0;i<citations.size();i++){
                if(citations[i]>=mid){
                    cnt++;
                }
            }
            if(cnt>=mid){
                // 要找的答案在 [mid,right] 区间内
                left=mid;
            }else{
                // 要找的答案在 [0,mid) 区间内
                right=mid-1;
            }
        }
        return left;
}
相关推荐
智能与优化17 分钟前
动态库dll与静态库lib编程4:MFC规则DLL讲解
开发语言·c++·mfc
0~max~028 分钟前
OpenGL材质系统和贴图纹理
c++·游戏引擎·图形渲染
不是只有你能在乱世中成为大家的救世主1 小时前
学习第六十二行
c语言·c++·学习·gitee
CodeClimb1 小时前
【华为OD-E卷 - 服务失效判断 100分(python、java、c++、js、c)】
java·javascript·c++·python·华为od
CodeClimb1 小时前
【华为OD-E卷 - 九宫格按键输入 100分(python、java、c++、js、c)】
java·javascript·c++·python·华为od
14_111 小时前
Cherno C++学习笔记 P49 C++中使用静态库
c++·笔记·学习
Cedric_Anik1 小时前
数据结构——链表
数据结构·链表
pumpkin845142 小时前
C++移动语义
开发语言·c++
起名方面没有灵感2 小时前
力扣23.合并K个升序链表
java·算法
啊烨疯狂学java2 小时前
0105java字节面经
java·jvm·算法