LeetCode题练习与总结:H 指数 Ⅱ--275

227 篇文章 0 订阅
137 篇文章 0 订阅

一、题目描述

给你一个整数数组 citations ,其中 citations[i] 表示研究者的第 i 篇论文被引用的次数,citations 已经按照 升序排列 。计算并返回该研究者的 h 指数。

h 指数的定义:h 代表“高引用次数”(high citations),一名科研人员的 h 指数是指他(她)的 (n 篇论文中)至少 有 h 篇论文分别被引用了至少 h 次。

请你设计并实现对数时间复杂度的算法解决此问题。

示例 1:

输入:citations = [0,1,3,5,6]
输出:3
解释:给定数组表示研究者总共有 5 篇论文,每篇论文相应的被引用了 0, 1, 3, 5, 6 次。
     由于研究者有3篇论文每篇 至少 被引用了 3 次,其余两篇论文每篇被引用 不多于 3 次,所以她的 h 指数是 3

示例 2:

输入:citations = [1,2,100]
输出:2

提示:

  • n == citations.length
  • 1 <= n <= 10^5
  • 0 <= citations[i] <= 1000
  • citations 按 升序排列

二、解题思路

  1. 首先,根据题目要求,我们需要找到最大的 h 值,使得至少有 h 篇论文的引用次数大于或等于 h。
  2. 因为数组已经按照升序排列,我们可以使用二分查找的方法来寻找这个 h 值。
  3. 在二分查找的过程中,我们需要检查 mid 位置的引用次数是否满足条件,即 citations[mid] >= n - mid,其中 n 是数组的长度。
  4. 如果满足条件,说明可能存在更大的 h 值,因此我们将 left 移动到 mid + 1 的位置继续查找。
  5. 如果不满足条件,说明 h 值应该小于 mid,因此我们将 right 移动到 mid - 1 的位置继续查找。
  6. 当 left 超过 right 时,停止查找,此时 right 就是我们要找的 h 值。

三、具体代码

class Solution {
    public int hIndex(int[] citations) {
        int n = citations.length;
        int left = 0, right = n - 1;
        
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (citations[mid] >= n - mid) {
                // 满足条件,可能存在更大的 h 值
                right = mid - 1;
            } else {
                // 不满足条件,h 值应该小于 mid
                left = mid + 1;
            }
        }
        
        // 当循环结束时,right + 1 就是 h 指数
        return n - left;
    }
}

这段代码中,left 最终会停在第一个不满足 citations[mid] >= n - mid 的位置,而 n - left 就是我们要求的 h 指数。因为 left 指向的是第一个引用次数小于论文数量的索引,所以 n - left 就是从该索引到数组末尾的论文数量,即至少有 n - left 篇论文的引用次数大于或等于 n - left

四、时间复杂度和空间复杂度

1. 时间复杂度
  • 代码中使用了二分查找算法,其核心是一个 while 循环,该循环会在每次迭代中将搜索范围减半。
  • 在最坏的情况下,循环会执行直到 left 超过 right,即当搜索范围缩小到无法再进行分割时。
  • 在每次迭代中,搜索范围都会从 [left, right] 变为 [left, mid - 1] 或 [mid + 1, right],其中 mid 是当前搜索范围的中间值。
  • 因此,循环的次数大约是 log(n),其中 n 是数组 citations 的长度。

综上所述,该算法的时间复杂度是 O(log n),即对数时间复杂度。

2. 空间复杂度
  • 空间复杂度主要考虑算法执行过程中所使用的额外空间。
  • 在这段代码中,我们使用了常数个额外空间,即 leftright 和 mid 这三个整型变量。
  • 这些变量占用的空间不会随着输入数组 citations 的大小而改变。

因此,该算法的空间复杂度是 O(1),即常数空间复杂度。

五、总结知识点

  • 类定义

    • class Solution 定义了一个名为 Solution 的类。
  • 方法定义

    • public int hIndex(int[] citations) 定义了一个公共方法 hIndex,它接受一个整数数组 citations 作为参数,并返回一个整数。
  • 变量声明和初始化

    • int n = citations.length; 声明并初始化了一个整数变量 n,用于存储数组 citations 的长度。
    • int left = 0, right = n - 1; 同时声明并初始化了两个整数变量 left 和 right,分别用于二分查找的左右边界。
  • 循环结构

    • while (left <= right) 使用了一个 while 循环来执行二分查找,直到 left 大于 right
  • 二分查找算法

    • int mid = left + (right - left) / 2; 计算中间位置 mid,防止 left 和 right 相加时可能发生的整数溢出。
    • 根据中间位置的值与 n - mid 的比较结果来调整搜索范围。
  • 条件判断

    • if (citations[mid] >= n - mid) 检查中间位置的论文引用次数是否满足 h 指数的条件。
    • else 分支处理不满足条件的情况。
  • 数组访问

    • citations[mid] 访问数组 citations 中索引为 mid 的元素。
  • 整数运算

    • 使用基本的整数加减和比较运算来调整 left 和 right 的值。
  • 算法逻辑

    • 代码的逻辑基于二分查找算法,用于在有序数组中找到满足特定条件的最大值。
  • 边界条件处理

    • 在二分查找的过程中,通过调整 left 和 right 的值来缩小搜索范围,直到找到正确的 h 指数。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一直学习永不止步

谢谢您的鼓励,我会再接再厉的!

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

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

打赏作者

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

抵扣说明:

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

余额充值