【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;
}
相关推荐
code bean1 小时前
【LangChain 】 自定义解析器实战指南:从原理到 10 个业务场景落地
算法·langchain
Little At Air1 小时前
LinuxOS阻塞队列模型(单生产者单消费者)
linux·数据结构·c++
念恒123061 小时前
基础IO(一切皆文件)
linux·c语言·c++·算法
Purple Coder1 小时前
上海吃点好的
面试
d111111111d1 小时前
MQTT+STM32+云平台+AT命令的编写
服务器·笔记·stm32·单片机·嵌入式硬件·算法
铁皮哥2 小时前
【力扣题解】LeetCode 25. K 个一组翻转链表
java·数据结构·windows·python·算法·leetcode·链表
Henray20242 小时前
LRU缓存设计与实现
java·面试
Irissgwe2 小时前
四、进程控制(进程创建与终止)
linux·c++·进程·系统编程·fork·进程创建·进程终止
代钦塔拉2 小时前
第一篇:工业级 C++/Qt 项目头文件包含原则:告别循环依赖与编译玄学
开发语言·c++·qt
ZOOOOOOU2 小时前
云平台赋能门禁终端,打造智慧社区一体化管理
大数据·数据结构·架构