274. H 指数
题意:
给你一个整数数组
citations
,其中citations[i]
表示研究者的第i
篇论文被引用的次数。计算并返回该研究者的h
指数。根据维基百科上 h 指数的定义:
h
代表“高引用次数” ,一名科研人员的h
指数 是指他(她)至少发表了h
篇论文,并且每篇论文 至少 被引用h
次。如果h
有多种可能的值,h
指数 是其中最大的那个。
【输入样例】
citations = [3,0,6,1,5]
【输出样例】
3
解题思路:
1. 先排序:[0,1,3,6,5]
2.从后往前遍历,当citations[i] > h时,表示找到了一篇被至少引用了h+1次的论文
3. 根据案例详细讲解:
· h初始值为0,i=citations.length -1;
· 第一步:citations[i] > h,成立,因为5>0,找到了一篇至少被引用1次的论文,++h,--i;
· 第二步:citations[i] > h,成立,因为6>1,找到了一篇至少被引用2次的论文,++h,--i;
· 第三步:citations[i] > h,成立,因为3>2,找到了一篇至少被引用3次的论文,++h,--i;
· 第四步:citations[i] > h,不成立,因为1<3,循环结束;
· 一共有三篇,至少被引用了3次,这里要注意的是,因为数组已经做了升序排序,所以第三步中,citations[i]的值为3,肯定是小于第一步和第二步的citations[i]的值的,所以3篇引用超过3是合理的。
class Solution {
public int hIndex(int[] citations) {
//1.先排序
Arrays.sort(citations);
int h=0,i = citations.length-1;
//i>=0是判断数组下标是否越界
//citations[i] >h ,是指找到了一篇被至少引用了h+1次的论文
while(i >= 0 && citations[i] > h){
++h;
--i;
}
return h;
}
}
时间: 击败了84.59%
内存: 击败了57.45%
解题思路2:计数排序
1.使用一个数组counter用来记录当前引用次数的论文有几篇
2.因为H指数的定义,是至少发表了h篇论文,并且这h篇论文分别至少被引用了h次。所以这里一个很重要的点就是,H指数不可能大于总的论文数。所以这里,计数排序的统计数组只要有原始数组那么大就够用了。
3.欧克了,到这里就是计数排序的思想了,然后输出的时候就是判断一下。
4.从后遍历去计算的时候也是一样的,counter数组的下标表示的引用次数,suo'yi
class Solution {
public int hIndex(int[] citations) {
//计数排序
int n=citations.length,tot = 0;
int[] counter = new int[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;
}
}
时间: 击败了100.00%
内存: 击败了69.88%
238.除自身以外数组的乘积
题意:
给你一个整数数组
nums
,返回 数组answer
,其中answer[i]
等于nums
中除nums[i]
之外其余各元素的乘积 。题目数据 保证 数组
nums
之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。请不要使用除法,且在
O(n)
时间复杂度内完成此题。
【输入样例】
nums= [1,2,3,4]
【输出样例】
[24,12,8,6]
解题思路:直接前缀积和后缀积
prev[i]:i之前所有数的乘积,所以prev[0]=1;乘法,初始值为1!!!
last[i]:i之后所有数的乘积,所以last[nums.length-1]=1,因为后面没有数了
class Solution {
public int[] productExceptSelf(int[] nums) {
int[] prev = new int[nums.length];
int[] last = new int[nums.length];
int[] answer = new int[nums.length];
prev[0] = 1;
last[nums.length-1] = 1;
for(int i=1;i<nums.length;++i){
prev[i] = prev[i-1]*nums[i-1];
}
for(int i=nums.length-2;i>=0;--i){
last[i] = last[i+1] * nums[i+1];
}
for(int i=0;i<nums.length;++i){
answer[i] = prev[i] * last[i];
}
return answer;
}
}
时间: 击败了100.00%
内存: 击败了97.49%
溜了溜了~~