【刷题笔记】H指数||数组||二分查找的变体

news2024/9/29 21:33:49

H指数

1 题目描述

https://leetcode.cn/problems/h-index/

给你一个整数数组 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


2 思路

反正不是我想出来的,随便写写

解题方法来源

这道题也是一道“翻译不当人”的典范,我们可以将这句话重新翻译一下

找到一个阈值h,数组中大于等于h的元素数量也大于等于h。同时保证阈值为h+1的时候,找不到足够数量的元素个数。

然后我们更加格式化地理解一下上面这句话:假设有一个统计函数counter(c)来统计数组中大于等于c的元素个数,counter(h) >= h, counter(h+1) < h+1

比如我们设citations=[13, 7, 6, 18, 12, 20, 20, 3, 0, 7],我们用gif的形式来表现当c=1、2、3...10的时候,数组中满足条件的元素个数。

在这里插入图片描述

counter(1) = 9 >= 1
counter(2) = 9 >= 2
counter(3) = 9 >= 3
counter(4) = 8 >= 4
counter(5) = 8 >= 5
counter(6) = 8 >= 6
counter(7) = 7 >= 7
-------------------
counter(8) = 5 < 8
counter(9) = 5 < 9
counter(10) = 5 < 10

我们用下图表示:

在这里插入图片描述

假设我们有一个数组[1, 2, ... , len(citiations)](设为nums),其中一定有一个分界线h,左和右分别表示满足或者不满足条件。

而当我们将上述数组替换成counter(c),即counters

在这里插入图片描述

很明显,counters数组是一个有序的、递减的数组。

在这里插入图片描述

好像事情朝着有趣的方向发展了,我们有一个有序数组counters,我们有一个判定条件counters[i] >= i+1(i在这里是下标),我们需要从有序数组中找到最后一个符合条件的元素

But, 如果我们对[1, 2, ... , len(citiations)](设为nums)数组进行遍历,对每个元素都施加counter函数来获得最终的counters数组,太耗时了。我们看看,能不能对上面的表述进行一些改造,毕竟nums和counters是一一对应的,我们可以在遍历到nums对应的元素时,再计算对应的counter:

我们有一个有序数组[1, 2, … , len(citiations)](表示为nums),我们有一个判定条件counter(nums[i]) >= i+1(i在这里是下标),我们需要从有序数组中找到最后一个符合条件的元素

在二分法中,我比较喜欢直接使用第1个元素、第2个元素、……、第n个元素这样的方式来指示元素的位置。

二分法中具有两个关键问题:

  • mid元素的下标计算
  • left指针和right指针的跳转方式

mid的计算,其实和left以及right指针的跳转方式相关。比如我们这个题目中,需要找到最后一个符合条件的元素。

也就是说,假设counter(nums[mid]) >= nums[mid],我们知道nums[mid]满足条件,但是nums[mid+1]还满足吗?不一定!所以left就 不能 直接跳转到mid的右边,而是 只能 直接跳转到mid上。

 if (counter(cs, nums[mid_index]) >= nums[mid_index]) {
        l = real_mid;
    } else {
        r = real_mid - 1;
    }

在这里插入图片描述

那么我们如何计算mid呢?这就需要我们考虑当只剩下两个元素的时候,mid到底是在left上还是在right上。如果让mid=left,下一步如果left需要跳转,left=mid,然后mid=left。。。。。。无限循环。

所以我们先看怎么跳转,再回过头想怎么计算mid。

也就是说,如果当前的[left~right]之间的元素个数为偶数,我们需要让mid指针指向中间两个元素的后一个元素。

class Solution {
    public int hIndex(int[] cs) {
        int[] nums = new int[cs.length];
        for (int i = 0; i < cs.length; i++) {
            nums[i] = i + 1;
        }
        int l = 1;
        int r = cs.length;

        while (l < r) {
            int mid_index = ((l + r) / 2); // 注意,我们这里的l和r都是元素的真实位置(从1开始),而不是索引(从0开始),
            // (l + r) / 2 在奇数情况下是中间元素的位置,
            // 偶数情况下是两个中间元素的前一个,同时也是后一个元素在数组中的索引位置。
            int real_mid = mid_index + 1; // 中间两个元素中后一个的元素的真实位置
            if (counter(cs, nums[mid_index]) >= nums[mid_index]) {
                l = real_mid; // left转移到mid
            } else {
                r = real_mid - 1; // right转移到mid - 1
            }
        }
        return counter(cs, l) >= l ? l : 0; // 有两种情况,一个是cs中只有一个元素,另一种情况是所有元素都为0

    }
    int counter(int[] cs, int mid) {
        int ans = 0;
        for (int i : cs) if (i >= mid) ans++; // 计算citiations中大于等于mid的元素数量。
        return ans;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1261884.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

9位院士Science发表长文:人工智能的进展、挑战与未来

源自&#xff1a;量子位 “人工智能技术与咨询”发布 2023年&#xff0c;海内外9位院士及12位专家在Science《科学》合作期刊Intelligent Computing发表长篇综述论文《智能计算的最新进展、挑战和未来》。文章全面阐述了智能计算的理论基础、智能与计算的技术融…

C#开发的OpenRA游戏之属性SelectionDecorations(12)

C#开发的OpenRA游戏之属性SelectionDecorations(12) 前面分析了显示选择框的指示器类SelectionBoxAnnotationRenderable,它的作用就是画一个四个角的方角。 这个类是在属性SelectionDecorations里调用的,如下: protected override IEnumerable<IRenderable> Rende…

滴滴打车app出现系统异常,已过12小时,部分功能仍未完全恢复

据多地用户反馈&#xff0c;滴滴出行APP无法使用。11月27日深夜&#xff0c;上海、北京、广州等多地滴滴用户反馈&#xff0c;滴滴出行APP无法使用&#xff0c;地图无法加载。 不少网约车司机反映&#xff0c;“滴滴出行”系统出现故障&#xff0c;导致无法接单、定位混乱等情况…

有哪些值得推荐的数据可视化工具?

1 数据可视化工具的种类和应用场景 数据可视化工具的多样性使其能够满足不同用户的需求。一般而言&#xff0c;这些工具可分为开源版和商业版两大类。开源版特点&#xff1a;自由开源&#xff1a; 开源版数据可视化工具通常以免费形式提供&#xff0c;允许用户自由使用和修改源…

Nacos整合实际应用案例

Nacos数据隔离模型 公司->命名空间->分组->服务 命名空间通常用于隔离不同微服务之间的配置 分组用于隔离相同微服务下不同环境的配置 版本对应关系 https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E 应用案例 <par…

Apache Airflow (十四) :Airflow分布式集群搭建及测试

&#x1f3e1; 个人主页&#xff1a;IT贫道_大数据OLAP体系技术栈,Apache Doris,Clickhouse 技术-CSDN博客 &#x1f6a9; 私聊博主&#xff1a;加入大数据技术讨论群聊&#xff0c;获取更多大数据资料。 &#x1f514; 博主个人B栈地址&#xff1a;豹哥教你大数据的个人空间-豹…

jquery 地址四级联级显示 不默认选择

代码效果 <body class"bgca"><img src"./files/joinTooBg.png" style"width: 100%;object-fit: cover;" alt""><!--填写申请资料--><section><div class"zi-liao"><h3 class"zong-h…

Apache Flink(一):Apache Flink是什么?

🏡 个人主页:IT贫道_大数据OLAP体系技术栈,Apache Doris,Clickhouse 技术-CSDN博客 🚩 私聊博主:加入大数据技术讨论群聊,获取更多大数据资料。 🔔 博主个人B栈地址:豹哥教你大数据的个人空间-豹哥教你大数据个人主页-哔哩哔哩视频 目录

搜维尔科技:8K!光线追踪!超大视场角!Varjo震撼发布XR-4系列

VR/XR硬件厂商Varjo发布了新一代XR-4系列头显—XR-4、XR-4 Focal Edition和XR-4 Secure Edition&#xff0c;升级后的头显提供了与自然视觉几乎无异的虚拟和混合现实体验。 划重点-新一代XR-4系列头显小编总结如下&#xff1a; 8K分辨率&#xff0c;高达120超大视场角&#xf…

Jmeter-分布式压测(远程启动服务器,windows)

1 前提条件 JDK已部署&#xff0c;版本一致Jmeter已部署&#xff0c;版本一致多台服务器连接的同一网络(例如&#xff1a;同一wifi)防火墙处于关闭状态&#xff08;或者对应默认端口处于开放状态&#xff09;虚拟网络适配器都处于关闭状态查找到每一台服务器的IP 2 主服务器配…

从四个典型场景看如何将数据集成“用到实处”

一、数据集成概念 数据集成是指将来自不同数据源的数据整合到一个统一的数据存储中&#xff0c;并确保这些数据能够互相关联、交换和共享的过程。在数据集成的过程中&#xff0c;数据通常需要经过清洗、转换和统一格式化等步骤&#xff0c;以确保数据的一致性、完整性和可用性…

第71讲:MySQL锁机制详解:表级锁、元数据锁和意向锁的全面解析与实践指南

MySQL中的表级锁 文章目录 MySQL中的表级锁1.MySQL中表级锁的概念2.表锁的概念以及基本使用2.1.表锁的分类以及概念2.2.表锁的使用语法2.3.表共享读锁的基本使用2.4.表独占写锁的基本使用 3.元数据锁的概念以及基本使用3.1.元数据锁的概念3.2.常见的SQL操作所对应的元数据锁3.3…

Java小游戏 王者荣耀

GameFrame类 所需图片&#xff1a; package 王者荣耀;import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.io.File; import java.util.ArrayLis…

【C++】什么是模板?怎样使用模板?

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 目录 前言 1.函数模板 1.1函数模板概念 1.2函数…

ecology主表checkBox按钮给明细表浏览按钮赋值

需求&#xff1a; 通过上面图片红框中的单选按钮&#xff0c;将对应的负责人赋值到明细表的负责人位置。 核心代码&#xff1a; <script> jQuery(document).ready(function(){WfForm.bindFieldChangeEvent("field17616", function(obj,id,value){ SelectVa…

JAVA进阶之路JVM-2:类加载机制,类的生命周期,类加载过程,类加载时机,类加载器,双亲委派模型,对象创建过程

JVM类加载机制 类加载 ​ 在JVM虚拟机实现规范中&#xff0c;通过ClassLoader类加载把*.class字节码文件&#xff08;文件流&#xff09;加载到内存&#xff0c;并对字节码文件内容进行验证&#xff0c;准备&#xff0c;解析和初始化&#xff0c;最终形成可以被虚拟机直接使用…

浙江启用无人机巡山护林模式,火灾扑救效率高

为了保护天然的森林资源&#xff0c;浙江当地林业部门引入了一种创新技术&#xff1a;林业无人机。这些天空中的守护者正在重新定义森林防火和护林工作的方式。 当下正值天气干燥的季节&#xff0c;这些无人机开始了它们的首次大规模任务。它们在指定的林区内自主巡逻&#xff…

Win7 SP1 x64 安装 Python 出错解决方法

1 双击安装 python-3.7.9.exe &#xff0c;提示出错&#xff0c;log.file 显示需要 KB2533623&#xff0c;但在Microsoft Update Catalog 没有搜到&#xff0c;实验 KB4474419 也可以。 2 Microsoft Update Catalog 搜索 KB4474419 并下载&#xff0c;安装&#xff0c;重启电脑…

聊聊如何进行代码混淆

​ 前言什么是代码混淆代码混淆&#xff0c;是指将计算机程序的代码&#xff0c;转换成一种功能上等价&#xff0c;但是难于阅读和理解的形式的行为。 代码混淆常见手段1、名称混淆 将有意义的类&#xff0c;字段、方法名称更改为无意义的字符串。生成的新名称越短&#xff0…

Windows系统下搭建PXE Server

在给一台服务器初始安装OS时一般有以下几种方式&#xff1a; 1、通过BMC挂载iso镜像来安装&#xff1b; 2、通过U盘启动来安装&#xff1b; 3、通过网络启动来安装&#xff1b; 方式1和方式2只能一台一台地进行&#xff0c;且需要有键盘和显示器&#xff0c;效率低下&#xff…