【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;
}
相关推荐
weixin_537590456 分钟前
【任务6.13】计算肇事汽车号码
c++·算法·汽车
从今天开始学习Verilog15 分钟前
FFT算法实现之fft IP核
算法·fpga开发
天天摸鱼的java工程师24 分钟前
🔧 MySQL 索引的设计原则有哪些?【原理 + 业务场景实战】
java·后端·面试
两颗泡腾片28 分钟前
黑马程序员C++核心编程笔记--类和对象--运算符重载
c++·笔记
用户6869161349031 分钟前
1999年NOIP普及组旅行家的预算(洛谷P1016):贪心算法实战指南
c++
Enddme1 小时前
《面试必问!JavaScript 中this 全方位避坑指南 (含高频题解析)》
前端·javascript·面试
程序员编程指南1 小时前
Qt 与 WebService 交互开发
c语言·开发语言·c++·qt·交互
荼蘼1 小时前
基于 KNN 算法的手写数字识别项目实践
人工智能·算法·机器学习
运维成长记1 小时前
关于linux运维 出现高频的模块认知
运维·职场和发展·云计算
溟洵1 小时前
Qt 窗口 工具栏QToolBar、状态栏StatusBar
开发语言·前端·数据库·c++·后端·qt