Java【数据结构】二分查找

🌞 题目:

🌏在有序数组A中,查找目标值target
🌏如果找到返回索引
🌏如果找不到返回-1

算法描述解释
前提给定一个内含n个元素的有序数组A,满足A0<=A1<=A2<=·······<=An-1,一个待查值target
1设置left=0;right = n - 1
2如果left > right ,结束查找,没找到
3设置mid = (left + right )/2,mid为中间索引
4如果target < Am,设置right = mid -1,跳到第2步
5如果target > Am,设置left = mid +1,跳到第2步
6如果Am = target,结束查找,找到了

算法实现

 public  int binarySearch(int[] arr,int target) {int left = 0;int right = arr.length-1;while(left<=right) {int mid = (left+right)>>>1;if(target < arr[mid]) {right = mid - 1;}else if (arr[mid] < target) {left = mid + 1;}else {return mid;}}return -1;}

注解:

1.为什么while循环条件是left<=right,而不是left<right?
因为当left=right时,mid=left=right可能为我们想要查找的值

2.为什么mid = (left+right)>>>1,而不是(left+right)/2呢? >>>是无符号右移,无符号右移一位相当于除2取整。 不用(left+right)/2原因是,当left+right的值超过int类型的正整数最大范围,其值就会由正变负

在其他的资料中二分查找与这个代码不一样,

✈️ 二分查找的改动版

public static int binarySearch1(int[] arr,int target) {int left=0;int right = arr.length;      //第一处改动while(left < right) {        //第二处改动int mid = (left+right)>>>1;if(target < arr[mid]) {right = mid;          //第三处改动}else if (arr[mid] < target) {left = mid + 1;}else {return mid;}}return -1;}

⛵️注解

right=arr.length,作为一个边界存在,left可能为我们的查找目标,但是right一定不是我们要找到的目标

🚀图解演示:

查找13
在这里插入图片描述

⛽️在Java中其实已经提供了二分查找的方法binarySearch

public class Test {public static void main(String[] args) {int[] arr ={1,2,3,4,5,5,6};int target = Arrays.binarySearch(arr,3);System.out.println(target);}
}

🚠运行结果:

2

在这里插入图片描述

🚩二分查找对重复元素的处理

📍重复元素最靠右的元素

说明:查找元素为重复元素的话,会查找到最右边的重复元素
Returns:
找到则返回最靠右索引
找不到返回-1

//重复元素最靠右的元素
public class Test5 {public static int binarySearch2(int[] arr,int target) {int left = 0;int right = arr.length-1;int cand = -1;while (left <= right) {int mid = (left + right)>>>1;if(target < arr[mid]) {right = mid-1;} else if (arr[mid] < target) {left = mid+1;}else {cand = mid;left = mid+1;}}return cand;}
}

说明:返回<=target的最右边的索引
Returns:
找到则返回最靠右索引
找不到返回小于target最右边的索引

 public static int binarySearchRightMost(int[] arr,int target){int left = 0;int right = arr.length-1;while(left <= right) {int mid = (left + right )>>>1;if(target < arr[mid]){right = mid-1;}else {left = mid + 1;}}return left-1;}

📍重复元素最靠左的元素

说明:查找元素为重复元素的话,会查找到最左边的重复元素
Returns:
找到则返回最靠左索引
找不到返回-1

 public static int binarySearch2(int[] arr,int target) {int left = 0;int right = arr.length-1;int cand = -1;while (left <= right) {int mid = (left + right)>>>1;if(target < arr[mid]) {right = mid-1;} else if (arr[mid] < target) {left = mid+1;}else {cand = mid;right = mid - 1;}}return cand;}

说明:
返回>=target最左边的索引
Returns:
找到则返回最靠左索引
找不到返回比target大的最左边索引

 public static int binarySearchLeftMost(int[] arr,int target) {int left=0;int right = arr.length-1;while(left <= right) {int mid = (left + right)>>>1;if(target <= arr[mid]) {right = mid - 1;}else  {left = mid + 1;}}return left;}

图解:
在这里插入图片描述

🚆leetcode二分查找题

1️⃣1.给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
⏩ 链接: 二分查找

提示:
你可以假设 nums 中的所有元素是不重复的。
n 将在 [1, 10000]之间。
nums 的每个元素都将在 [-9999,9999]之间。

class Solution {public int search(int[] nums, int target) {int i=0;int j = nums.length-1;while(i<=j){int m=(i+j)>>>1;if(target<nums[m]){j=m-1;}else if(nums[m]<target){i=m+1;}else{return m;}}return -1;}
}

2️⃣2.给定一个排序的整数数组 nums 和一个整数目标值 target ,请在数组中找到 target ,并返回其下标。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。
⏩ 链接: 搜索插入位置

class Solution {public int searchInsert(int[] nums, int target) {int left=0;int right = nums.length-1;while(left <= right) {int mid = (left + right)>>>1;if(target <= nums[mid]) {right = mid - 1;}else  {left = mid + 1;}}return left;}
}

3️⃣3.给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。

如果数组中不存在目标值 target,返回 [-1, -1]。

你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。
⏩ 链接: 在排序数组中查找元素的第一个和最后一个位置

class Solution {public int[] searchRange(int[] nums, int target) {int x=left(nums,target);if(x==-1){return new int[]{-1,-1};}else{return new int[]{x,right(nums,target)};}}public int left(int[] nums,int target) {int i=0;int j=nums.length-1;int cand=-1;while(i<=j){int  m=(i+j)>>>1;if(target<nums[m]){j=m-1;}else if(nums[m]<target){i=m+1;}else{cand=m;j=m-1;}}return cand;}public int right(int[] nums,int target) {int i=0;int j=nums.length-1;int cand=-1;while(i<=j){int  m=(i+j)>>>1;if(target<nums[m]){j=m-1;}else if(nums[m]<target){i=m+1;}else{cand=m;i=m+1;}}return cand;}
}

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

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

相关文章

mysql 8.0安装

操作系统&#xff1a;22.04.1-Ubuntu apt 安装命令 sudo apt install mysql-client-core-8.0 sudo apt install mysql-server-8.0终端输入 mysql 可以直接免密登录 如果此时提示需要密码&#xff0c;则可以进入配置文件&#xff0c;设置免密登录 sudo vim /etc/mysql/mysq…

【探索Linux】—— 强大的命令行工具 P.5(yum工具、git 命令行提交代码)

阅读导航 前言一、软件包管理器 yum1.yum的概念yum的基本指令使用例子 二、git 命令行提交代码总结温馨提示 前言 前面我们讲了C语言的基础知识&#xff0c;也了解了一些数据结构&#xff0c;并且讲了有关C的一些知识&#xff0c;也学习了一些Linux的基本操作&#xff0c;也了…

第3章 CPU微架构

3.1 指令集架构 指令集ISA是软件用来与硬件通信的词汇集合&#xff0c;定义了软件和硬件之间的通信协议。Intel x86、ARM v8、RISC-V是当今广泛使用指令集架构的实例。ISA开发者通常要确保符合规范的软件或固件能在使用该规范构建的任何处理器上执行。广泛部署的ISA组织通常还…

20W IP网络吸顶喇叭 POE供电吸顶喇叭

SV-29852T 20W IP网络吸顶喇叭产品简介 产品用途&#xff1a; ◆室内豪华型吸顶喇叭一体化网络音频解码扬声器&#xff0c;用于广播分区音频解码、声音还原作用 ◆应用场地如火车站、地铁、教堂、工厂、仓库、公园停车场等&#xff1b;室内使用效果均佳。 产品特点&#xff…

vue-router中的一些 API

在Vue.js的vue-router中&#xff0c;一些重要api 1、RouterHistory&#xff1a;这是 vue-router 提供的路由历史记录对象。它可以跟踪当前页面的路由历史&#xff0c;并提供一些方法和属性来管理导航和历史记录。在 vue-router 中&#xff0c;有两种类型的路由历史记录对象&…

pytorch_lightning报错 You requested gpu: [1],But your machine only has: [0]

pytorch_lightning报错 You requested gpu: [1]&#xff0c;But your machine only has: [0] 问题及分析 报错图片如下&#xff1a; 分析 gpu:[1]指代的gpu的标号&#xff0c;如果笔记本中只包含一个GPU&#xff0c;一般序号为[0].所以无法找到程序指定的GPU。 解决方法 …

机器学习之逻辑回归

import numpy as np import pandas as pd from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LogisticRegression # 获得数据 names[Sample code number,Clump Thickness,Uniformity…

编程语言学习笔记-架构师和工程师的区别,PHP架构师之路

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌&#xff0c;CSDN博客专家&#xff0c;阿里云社区专家博主&#xff0c;2023年6月CSDN上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责…

Egg.js构建一个stream流式接口服务

经常需要用到 stream 流式接口服务,比如&#xff1a;大文件下载、日志实时输出等等。本文将介绍如何使用Egg.js构建一个 stream 流式接口服务。 一、准备工作 目录结构&#xff1a; app//controllerindex.jstest.txttest.shindex.js 控制器test.txt 测试文件&#xff0c;最好…

5G+AI数字化智能工厂建设解决方案PPT

导读&#xff1a;原文《5GAI数字化智能工厂建设解决方案》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。数字化智能工厂定义 智能基础架构协同框架 - 端、边、云、网…

激光雷达 01 线数

一、线数 对于 360 旋转式和一维转镜式架构的激光雷达来说&#xff0c;有几组激光收发模块&#xff0c;垂直方向上就有几条线&#xff0c;被称为线数。这种情况下&#xff0c;线数就等同于激光雷达内部激光器的数量[参考]。 通俗来讲&#xff0c;线数越高&#xff0c;激光器的…

npm run xxx 的时候发生了什么?(以npm run dev举例说明)

文章目录 一、去package.json寻找scripts对应的命令二、去node_modules寻找vue-cli-service三、从package-lock.json获取.bin的软链接1. bin目录下的那些软连接存在于项目最外层的package-lock.json文件中。2.vue-cli-service文件的作用3.npm install 的作用 总结 一、去packag…

Google API实战与操作

Google api实战与操作 一. Google API 权限配置二. 操作API2.1 引入依赖2.2 导入代码 Google官网 实现一套用java程序控制GoogleAPI实现自动生成监控日报等功能,具体能操作Gsheet及document 一. Google API 权限配置 打开上面官网,新建项目 启用API 搜索sheet及document …

【山河送书第七期】:《强化学习:原理与Python实战》揭秘大模型核心技术RLHF!

《强化学习&#xff1a;原理与Python实战》揭秘大模型核心技术RLHF&#xff01; 一图书简介二RLHF是什么&#xff1f;三RLHF适用于哪些任务&#xff1f;四RLHF和其他构造奖励模型的方法相比有何优劣&#xff1f;五什么样的人类反馈才是好反馈&#xff1f;六如何减小人类反馈带来…

LVGL图层的介绍

一.UI界面显示的图层 在lvgl开发的过程中&#xff0c;UI界面的显示都是位于lv_sct_act()图层 二.弹窗显示 lvgl开发过程中&#xff0c;有些窗口有可能在任何时候显示&#xff0c;比如错误信息弹窗&#xff0c;外部触发的一些中断。 这个时候&#xff0c;这些窗口不能建立在lv_s…

web前端开发基础入门html5+css3+js学习笔记(一)

目录 1.第一个前端程序2.前端工具的选择与安装3.VSCode开发者工具快捷键4.HTML5简介与基础骨架4.1 HTML5的DOCTYPE声明4.2 HTML5基本骨架4.2.1 html标签4.2.2 head标签4.2.3 body标签4.2.4 title标签4.2.5 meta标签 5.标签之标题5.1 快捷键5.1 标题标签位置摆放 6.标签之段落、…

LeetCode每日一题——2682. 找出转圈游戏输家

n 个朋友在玩游戏。这些朋友坐成一个圈&#xff0c;按 顺时针方向 从 1 到 n 编号。从第 i 个朋友的位置开始顺时针移动 1 步会到达第 (i 1) 个朋友的位置&#xff08;1 < i < n&#xff09;&#xff0c;而从第 n 个朋友的位置开始顺时针移动 1 步会回到第 1 个朋友的位…

leetcode 377. 组合总和 Ⅳ

2023.8.17 本题属于完全背包问题&#xff0c;乍一看和昨天那题 零钱兑换II 类似&#xff0c;但细看题目发现&#xff1a;今天这题是排列问题&#xff0c;而“零钱兑换II”是组合问题。排列问题强调顺序&#xff0c;而组合顺序不强调顺序。 这里先说个结论&#xff1a;先遍历物品…

并查集、树状数组

并查集、树状数组、线段树 并查集树状数组树状数组1 (单点修改&#xff0c;区间查询)树状数组2 (单点查询&#xff0c;区间修改) 并查集 【模板】并查集 题目描述 如题&#xff0c;现在有一个并查集&#xff0c;你需要完成合并和查询操作。 输入格式 第一行包含两个整数 …

Scala中的Either的用法

在 Scala 中&#xff0c;Either 是一种表示两种可能值的数据类型。它可以用来处理函数可能返回的两种不同类型的结果&#xff0c;通常用于错误处理或者结果分支情况。Either 有两个子类&#xff1a;Left 和 Right&#xff0c;其中 Left 通常用于表示错误或异常情况&#xff0c;…