【LeetCode-面试经典150题-day4】

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%

溜了溜了~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值