【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;
}
相关推荐
咔咔咔的8 分钟前
1930. 长度为 3 的不同回文子序列
c++
春日见2 小时前
丝滑快速拓展随机树 S-RRT(Smoothly RRT)算法核心原理与完整流程
人工智能·算法·机器学习·路径规划算法·s-rrt
Code小翊2 小时前
”回调“高级
算法·青少年编程
云里雾里!2 小时前
力扣 977. 有序数组的平方:双指针法的优雅解法
算法·leetcode·职场和发展
WYiQIU3 小时前
11月面了7.8家前端岗,兄弟们12月我先躺为敬...
前端·vue.js·react.js·面试·前端框架·飞书
一只侯子5 小时前
Face AE Tuning
图像处理·笔记·学习·算法·计算机视觉
Cinema KI5 小时前
吃透C++继承:不止是代码复用,更是面向对象设计的底层思维
c++
jianqiang.xue5 小时前
别把 Scratch 当 “动画玩具”!图形化编程是算法思维的最佳启蒙
人工智能·算法·青少年编程·机器人·少儿编程
不许哈哈哈6 小时前
Python数据结构
数据结构·算法·排序算法
J***79397 小时前
后端在分布式系统中的数据分片
算法·哈希算法