AcWing算法基础课-789数的范围-Java题解

heweilai-bolg-title-image-of-the-article

大家好,我是何未来,本篇文章给大家讲解《AcWing算法基础课》789 题——数的范围。本文详细解析了一个基于二分查找的算法题,题目要求在有序数组中查找特定元素的首次和最后一次出现的位置。通过使用两个二分查找函数,程序能够高效地处理大量查询,时间复杂度为 O(n log n),空间复杂度为 O(n)。文章从题目描述、算法思路、具体实现步骤到Java代码实现,全面展示了如何解决这一问题。

文章目录

  • ❓题目描述
  • 💡算法思路
  • ✅Java代码
  • 🔗参考

❓题目描述

给定一个按照升序排列的长度为 n 的整数数组,以及 q 个查询。

对于每个查询,返回一个元素 k 的起始位置和终止位置(位置从 0 开始计数)。

如果数组中不存在该元素,则返回 -1 -1

输入格式

第一行包含整数 n 和 q,表示数组长度和询问个数。

第二行包含 n 个整数(均在 1∼10000 范围内),表示完整数组。

接下来 q 行,每行包含一个整数 k,表示一个询问元素。

输出格式

共 q 行,每行包含两个整数,表示所求元素的起始位置和终止位置。

如果数组中不存在该元素,则返回 -1 -1

数据范围

1≤n≤100000
1≤q≤10000
1≤k≤10000

输入样例:

6 3
1 2 2 3 3 4
3
4
5

输出样例:

3 4
5 5
-1 -1

💡算法思路

  1. 使用二分查找算法findFristGreatOrEqual(int l, int r, int x)查找数组中元素 k 的开始位置
  2. 如果找到了 k 的开始位置,就返回元素 k 的开始位置,并使用findFirstLessOrEqual(int l, int r, int x)查找 k 的结束位置
  3. 如果没有找到 k 的开始位置,那么也不存在 k 的结束位置。直接返回-1 -1

具体实现步骤:

  1. 初始化输入流

    • 程序首先创建一个 StreamTokenizer 对象,用于从标准输入流中读取数据。这个对象通过 BufferedReaderInputStreamReader 来处理输入。
  2. 读取数组大小和查询次数

    • 程序调用 nextInt() 方法两次,分别读取数组的大小 n 和查询次数 q
  3. 读取数组元素

    • 程序使用一个循环,调用 nextInt() 方法 n 次,将输入的整数依次存储到数组 nums 中。
  4. 处理每个查询

    • 程序使用一个循环,处理 q 次查询。每次查询时,程序调用 nextInt() 方法读取一个整数 k,表示要查找的值。
  5. 查找首次出现的位置

    • 程序调用 findFristGreatOrEqual(0, n - 1, k) 方法,使用二分查找算法在数组中查找第一个大于或等于 k 的元素的位置。
    • 如果找到的位置上的元素等于 k,则说明 k 存在于数组中。
  6. 查找最后一次出现的位置

    • 如果 k 存在于数组中,程序调用 findFirstLessOrEqual(0, n - 1, k) 方法,使用二分查找算法在数组中查找第一个小于或等于 k 的元素的位置。
    • 这个位置即为 k 在数组中最后一次出现的位置。
  7. 输出结果

    • 如果 k 存在于数组中,程序输出 k 的首次和最后一次出现的位置。
    • 如果 k 不存在于数组中,程序输出 -1 -1
  8. 二分查找函数的实现

    •   findFristGreatOrEqual(int l, int r, int x)
      
      • 这个函数使用二分查找算法,在数组的 [l, r] 范围内查找第一个大于或等于 x 的元素的位置。
      • 通过不断缩小查找范围,最终找到目标位置。
    •   findFirstLessOrEqual(int l, int r, int x)
      
      • 这个函数使用二分查找算法,在数组的 [l, r] 范围内查找第一个小于或等于 x 的元素的位置。
      • 通过不断缩小查找范围,最终找到目标位置。

时间复杂度:O(n log n)
空间复杂度:O(n)

✅Java代码

import java.*;

public class Aw789 {

	// 创建一个StreamTokenizer对象,用于读取输入流
	static StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));

	// 读取下一个整数
	static int nextInt() throws IOException {
		in.nextToken();
		return (int) in.nval;
	}

	static int n, q, k;
	// 定义一个数组来存储输入的数字,数组大小为100010
	static int[] nums = new int[100000 + 10];

	public static void main(String[] args) throws IOException {
		// 读取数组的大小n和查询次数q
		n = nextInt();
		q = nextInt();
		// 读取n个整数并存储到数组nums中
		for (int i = 0; i < n; i++) {
			nums[i] = nextInt();
		}
		// 处理q次查询
		while (q-- > 0) {
			// 读取查询的数字k
			k = nextInt();
			// 查找第一个大于或等于k的元素的位置
			int left = findFristGreatOrEqual(0, n - 1, k);
			// 如果找到的元素等于k
			if (nums[left] == k) {
				// 输出第一个等于k的元素的位置和最后一个等于k的元素的位置
				System.out.println(left + " " + findFirstLessOrEqual(0, n - 1, k));
			} else {
				// 如果没有找到等于k的元素,输出-1 -1
				System.out.println("-1 -1");
			}
		}
	}

	// 二分查找第一个大于或等于x的元素的位置
	static int findFristGreatOrEqual(int l, int r, int x) {
		while (l < r) {
			int mid = l + r >> 1; // 计算中间位置
			if (nums[mid] >= x) {
				r = mid; // 如果中间元素大于或等于x,缩小右边界
			} else {
				l = mid + 1; // 否则,缩小左边界
			}
		}
		return l; // 返回找到的位置
	}

	// 二分查找第一个小于或等于x的元素的位置
	static int findFirstLessOrEqual(int l, int r, int x) {
		while (l < r) {
			int mid = (l + r + 1) >> 1; // 计算中间位置
			if (nums[mid] <= x) {
				l = mid; // 如果中间元素小于或等于x,缩小左边界
			} else {
				r = mid - 1; // 否则,缩小右边界
			}
		}
		return l; // 返回找到的位置
	}

}

🔗参考

  • https://www.acwing.com/problem/content/791/

作者:程序员何未来-heweilai.com


🔍推荐阅读

  1. AcWing算法基础课-788逆序对的数量-Java题解
  2. AcWing算法基础课-787归并排序-Java题解
  3. 博客赚钱全攻略:从新手到专家的变现之路

欢迎关注我的博客:@程序员何未来,持续为你输出有价值的技术文章~
你们的点赞👍 收藏⭐ 留言🗨️ 关注✅
是我持续创作,输出优质内容的最大动力!谢谢!

文章关键词:算法,计算机算法,算法题解,算法竞赛,Java,数据结构,AcWing算法基础课

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Mysql InnoDB 存储引擎简介

InnoDB 存储引擎是 Mysql 的默认存储引擎&#xff0c;它是由 Innobase Oy 公司开发的 Mysql 为什么默认使用 InnoDB 存储引擎 InnoDB 是一款兼顾高可靠性和高性能的通用存储引擎 在 Mysql 5.5 版本之前&#xff0c;默认是使用 MyISAM 存储引擎&#xff0c;在 5.5 及其之后版…

车型展示+接驳体验!苏州金龙海格客车闪耀汉诺威商用车展

德国当地时间9月16日&#xff0c;IAA汉诺威商用车展媒体日活动在德国汉诺威展览中心开幕。该展会自1897年首次举办以来&#xff0c;已有超过一个世纪的历史&#xff0c;是全球历史最长、规模最大、最具影响力的专业商用车展之一&#xff0c;更是世界商用车行业技术创新和发展趋…

实战案例(5)防火墙通过跨三层MAC识别功能控制三层核心下面的终端

如果网关是在核心设备上面&#xff0c;还能用MAC地址进行控制吗&#xff1f; 办公区域的网段都在三层上面&#xff0c;防火墙还能基于MAC来控制吗&#xff1f; 采用正常配置模式的步骤与思路 &#xff08;1&#xff09;配置思路与上面一样 &#xff08;2&#xff09;与上面区…

STM32 如何生成随机数

目录 一、引言 二、STM32 随机数发生器概述 三、工作原理 1.噪声源 2.线性反馈移位寄存器&#xff08;LFSR&#xff09; 3.数据寄存器&#xff08;RNG_DR&#xff09; 4.监控和检测电路&#xff1a; 5.控制和状态寄存器 6.生成流程 四、使用方法 1.使能随机数发生器 …

C++笔记---二叉搜索树

1. 二叉搜索树的概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: • 若它的左子树不为空&#xff0c;则左子树上所有结点的值都小于等于根结点的值。 • 若它的右子树不为空&#xff0c;则右子树上所有结点的值都大于等于…

数据结构—双向链表

结构 带头链表里的头结点&#xff0c;实际为“哨兵位”&#xff0c;哨兵位结点不存储任何有效元素&#xff0c;只是站在这里“放哨 的” 实现双向链表 List.h #pragma once#include<stdio.h> #include<stdlib.h> #include<assert.h> #include<stdbool…

“RISCV+AI”

概述 设计方案 主要有两种设计方案。 RISCV核ASIC RISCV核是标准的基于RISCV指令集的CPU设计&#xff0c;ASIC部分通常是基于RISCV自带的向量扩展指令集构建的向量处理器&#xff0c;或是自定义的矩阵计算单元。 根据CPUAI ASIC部件的接口可以分为紧耦合和松耦合的设计1。 …

基于python+django+vue的学生管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于协同过滤pythondjangovue…

【Python笔记】PyCharm大模型项目环境配置

一、PyCharm创建新项目 二、更新pip版本 ...>python.exe -m pip install --upgrade pip 三、生成所需requirements配置文件 ...>pip freeze > requirements.txt 四、安装所需组件requirements.txt ...>pip install -r requirements.txt

【Kubernetes】linux centos安装部署Kubernetes集群

【Kubernetes】centos安装Kubernetes集群 1、环境准备 系统centos7 配置yum源参考文章 Centos系统换yum源 yum -y update 步骤1-3是所有主机都要配置&#xff0c;主机名和hosts配置完后可以使用工具命令同步 1.1 主机 一主二从 主机名ipk8smaster192.168.59.148k8snode11…

Node.js 安装及项目实践

node.js安装 node安装&#xff0c;选择版本 一直next&#xff0c;或者自己修改路径&#xff0c;添加两个包 选择自己的安装的node的路径&#xff0c;cmd或者winr cmd 显示node与npm的版本号 node -vnpm -v可以跟着这个博客将node安装 2024最新版Node.js下载安装及环境配…

ZW3D二次开发_UI_非模板表单_设置表单显示位置

1.ZW3D弹出非模板表单时可以设置弹出位置&#xff08;居中、左下角、右上角等&#xff09; 2.假设已创建好非模板表单 3.在Form属性中添加form_pos属性 4.输入值 base,CTR,0.0 &#xff0c;如下图 也可以设置为其他值显示在不同的位置&#xff0c;如下 5.重新编译&#xff0c;…

新升级|优化航拍/倾斜模型好消息,支持处理多套贴图模型!

【天元轻量化软件】一直在不断地追求进步和完善&#xff0c;以满足更多用户的各种需求。 电脑登录天元官网免费体验&#xff1a;天元轻量化软件官网 本次我们对“智能PBR”功能进行了更新。更新后的“智能PBR”支持带多套贴图的模型进行使用。 本轮更新后&#xff0c;主要受益…

防火墙--NAT技术,基于源NAT,NAT服务器,双向NAT

文章目录 防火墙--NAT技术一、基于源NAT**方式**&#xff1a;NAT No-PATNAPT出接口地址方式Smart NAT三元组 NAT 二、基于服务器的NAT多出口场景下的NAT Server 三、双向NAT 防火墙–NAT技术 基于源NAT&#xff1a;用于将内部网络的私有IP地址转换为公共IP地址&#xff0c;以便…

51单片机应用开发---数码管的控制应用

实现目标 1、掌握数码管结构、驱动原理及应用&#xff1b; 2、掌握数码管段码表推导&#xff1b; 3、会编程让开发板8个数码管动态显示。 一、什么是数码管&#xff1f; 1.数码管定义 数码管&#xff0c;也称为LED数码管&#xff0c;基本单元是发光二极管(LED)。分为七段数…

【机器学习】--- 自监督学习

1. 引言 机器学习近年来的发展迅猛&#xff0c;许多领域都在不断产生新的突破。在监督学习和无监督学习之外&#xff0c;自监督学习&#xff08;Self-Supervised Learning, SSL&#xff09;作为一种新兴的学习范式&#xff0c;逐渐成为机器学习研究的热门话题之一。自监督学习…

某思CMS V10存在SQL注入漏洞

Fofa: product"魅思-视频管理系统" 框架:ThinkPHP 5,6 1 漏洞分析&复现 位于 /controller/Api.php 控制器中的getOrderStatus 方法POST传入&#xff0c;然后直接拼接了 orderSn 变量到 where 查询中&#xff0c;导致漏洞产生. /** * 查询订单支付状态 */ pub…

服务器——装新的CUDA版本的方法

服务器——装新的CUDA版本 一、进入 CUDA 版本列表二、根据自己服务器&#xff0c;选择对应的版本和配置三、使用管理员用户&#xff0c;运行下载和安装命令四、查看显卡驱动是否安装4.1 若安装了显卡驱动4.2 若显卡驱动没安装 参考文章 一、进入 CUDA 版本列表 CUDA Toolkit …

sqlgun靶场攻略

步骤一&#xff1a;打开页面 步骤二&#xff1a;测试回显点 -1union select 1,2,3# 步骤三&#xff1a;查看数据库名 -1union select 1,2,database()# 步骤四&#xff1a;查看表名 -1union select 1,2,group_concat(table_name) from information_schema.tables where table…

Double Write

优质博文&#xff1a;IT-BLOG-CN 一、存在的问题 为什么需要Double Write&#xff1a; InnoDB的PageSize是16kb&#xff0c;其数据校验也是针对这16KB来计算的&#xff0c;将数据写入磁盘是以Page为单位的进行操作的。而计算机硬件和操作系统&#xff0c;写文件是以4KB作为基…