力扣每日一题 275. H 指数 II

力扣刷题笔记 275. H 指数 II

1、问题描述

给定一位研究者论文被引用次数的数组(被引用次数是非负整数),数组已经按照 升序排列 。编写一个方法,计算出研究者的 h 指数。

h 指数的定义: “h 代表“高引用次数”(high citations),一名科研人员的 h 指数是指他(她)的 (N 篇论文中)总共有 h 篇论文分别被引用了至少 h 次。(其余的 N - h 篇论文每篇被引用次数不多于 h 次。)"

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/h-index-ii

2、示例

image-20210712112257526

说明:

如果 h 有多有种可能的值 ,h 指数是其中最大的那个。

3、问题分析和解答

在输入接口中,依照题意无论提供的是数组还是vector,元素都是升序排列的,即这个序列是一个有序表。此外对于数组也额外提供了数组的大小。

耐心读题,我们知道要得到h的值,需要在有序表中对数据进行比较。

那么有序表的搜寻的算法要么按顺序暴力搜索要么二分查找;

3.1 暴力求解

对于暴力搜索这个问题会有两种搜寻方案:

  • 从后往前遍历vector/array

    若有Vector中的升序元素A={0,1,2,3,4,5}和待比较集合U={0,1,2,3,4,5}

    由于是从后往前遍历vector那么需要做的就是按照题意,将vector中的元素倒序与U集合中的元素逐个比较,如5和0比较,4和1比较,一直比较下去我们会得到当A中元素为2时,此时2∈vector < 3∈U。由于vector升序,再往A的前面比较就没有意义了,所以h=3。

  • 从前往后遍历vector/array

    若有vector中的升序元素A={0,1,2,3,4,5}和待比较集合U={5,4,3,2,1,0}

    由于从后往前遍历vector那么需要做的也是将vector中的元素顺序与U集合中的元素逐个比较,如0和5比较,1和4比较,2和3比较,最后3和2比较,3>2,那么h = 3。

前后遍历都是一样的,这里给出从后往前遍历的程序:

class Solution {
public:
    int hIndex(vector<int>& citations) {
        int h = 0;
		for(int i = citations.size(); i > 0; i--){
			int last = citations.at(i-1);
			if(last > h){
				h++;
				continue;
			}
			break;
		} 
		return h;
    }
};

提交结果如下:

image-20210712142643261

3.2 二分求解

对于二分查找,我们需要找出一个元素的下标mid,从mid到vector序列末的文章个数记作PCout。记len = vector.size(),并且初始化right = len - 1, left = 0

  • 若有vector.at(mid)>=PCount,那么我们可以尝试让h值更大些,即调整让mid往左一些,调整右边边界right = mid -1
  • 若有vector.at(mid)<PCount,那么我们尝试让h值变小使之满足h值的定义,即调整让mid往右一些,调整左边边界left = mid + 1

然后确定下一次的mid。

直到不满足二分的条件:left<=right为止。

程序如下:

class Solution {
public:
    int hIndex(vector<int>& citations) {
		int len = citations.size();
		int left = 0, right = len - 1;	//定义左边边界和右边边界 
		
		while(left <= right){
			int mid = left +(right - left) / 2;
			if(citations.at(mid) >= len - mid){	//这里的mid是下标,所以直接相减就可以得到个数 
				right = mid - 1;
			}
			else{
				left = mid + 1;
			}
		}
		return len - left;
    }
};

运行结果:

image-20210712164236477

需要指出的是二分解法不一定比暴力求解来得更快,取决于样例的数值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Blanche117

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值