leetcode每日一题——274.H指数(面试经典150题)

一、题目描述与要求

274. H 指数 - 力扣(LeetCode)

题目描述

给你一个整数数组 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 次,其余两篇论文每篇被引用 不多于 3 次,所以她的 h 指数是 3。

示例2:

输入:citations = [1,3,1]
输出:1

提示

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

二、解题思路

总的思路:

       先分析题目,题目给了我们一个整数数组,数组中的元素分别代表对应论文被引用的次数。而我们所要做的就是统计出该作者至少发表了h篇论文,这h篇论文需要满足至少被引用了h次的条件。因而我们所要做的就是求出这个h,这个h需要取最大的。

       分析完题目之后我们开始解决问题。首先每篇论文都有对应的引用次数,而题目所给的数组是无序的,因此我们要找出具有共性(至少被引用了h次)的论文数量,我们可以先对整个数组进行排序,因为我们不需要知道具体是哪几篇论文,所以可以直接进行排序。(如果需要知道是哪几篇则需要借助别的方法来记录对应论文序号。)排序之后我们对某个具体的例子,一眼就能够看出h是多少。比如数组=3,0,6,1,5;排序后的结果为0,1,3,5,6,我们可以直接看出至少有3篇论文都至少被引用了3次。但我们需要让计算机来获取这个结果。

       这是我们可以想到,我们排序了之后,如果前面的论文能够满足至少被引用了h次,那么它后面的论文肯定也能够满足至少被引用了h次,因此我们需要在数组中找到最小的满足题目条件的论文。综上我们可以对数组从大到小进行遍历,将h初始化为0,如果引用次数>h则h++,同时i--。一直到找到最后一个引用次数≥h的元素时遍历结束。因为此时前面的论文肯定不能够满足至少被引用了h次的条件。为什么是引用次数>h,因为其>h就意味着它至少被引用了h+1次,那就能够满足至少被引用了h次的条件

具体步骤:

①定义qsort排序函数中的排序原则cmp函数为递增排序

②对所给数组进行排序

③初始化h和i

④逆序遍历排序后的数组并根据条件更新h并将i向前移动

⑤返回h


三、具体代码【C语言】

时间复杂度O(nlogn) 空间复杂度O(logn) 【主要花费在排序上】

int cmp(int *a, int *b) {
    return *a - *b;//顺序为递增
}

int hIndex(int* citations, int citationsSize){
    //qsort函数包含四个参数,分别是:1.数组名  2.元素个数(从前往后计算) 
    //3.数组元素所占字节(int,double,char等所占字节) 4.排序原则(递增,递减,奇偶交叉等)
    qsort(citations, citationsSize, sizeof(int), cmp);//将数组按照递增的顺序排序
    int h = 0, i = citationsSize - 1;//初始化h为0
    //从大到小遍历数组,当元素大于h时说明,当前论文至少被引用了h+1次因而将h++
    //因为我们是从大到小对数组进行遍历,因而当前面的论文满足引用次数时,后一篇论文也能满足至少被引用的次数
    //所以当我们找到小于等于h的元素时循环结束
    while (i >= 0 && citations[i] > h) {
        h++;
        i--;
    }
    return h;
}

你可能感兴趣的:(leetcode刷题,leetcode,面试,算法,c语言,排序算法)