数据结构与算法——Java实现 3.二分查找——Java版

devtools/2024/10/21 5:39:08/

放下不切实际的幻想,放下无法更改的过去,行云流水,任其行之

                                                                                                —— 24.8.31

一、二分查找——Java基础版

Java中的API——Arrays.binarySearch(数组,目标值)

返回的结果是插入点的位置

若在目标数组中找不到元素,则返回的是负的(插入该点的位置+1)

+1,是为了避免在第一个位置插入时,返回0与查找元素刚好处在第一个位置重复的这种情况,+1可以分辨这两种情况,观察是否返回的是负数

java">import java.util.Arrays;public class demo2BinarySearchJava {public static void main(String[] args) {int[] arr = {1,2,3,4,5,6,7,8,9,10};int target = -1;int res = Arrays.binarySearch(arr, target);// 找不到时,会返回负的(插入点的位置+1):-(low+1)    +1是为了区分在第一个0位置插入的情况System.out.println("res: " + res); // 11// 返回点的插入位置用i变量表示就可以if(res < 0){// Math.abs:绝对值函数// 插入点索引insertint insert = Math.abs(res+1);// 创建数组Bint[] arrB = new int[arr.length+1];// 数组拷贝 被拷贝数组 拷贝位置 目标新数组 拷贝起始位置 拷贝数据的长度System.arraycopy(arr,0,arrB,0,insert);// 将被插入点位置元素改为插入元素arrB[insert] = target;// 数组拷贝 将新插入元素后位置的函数插入到插入点位置System.arraycopy(arr,insert,arrB,insert+1,arr.length-insert);System.out.println(Arrays.toString(arrB));}}
}

二、二分查找——找到重复元素中元素的位置

1.找到重复元素中最左侧第一个出现元素的位置

当数组中存在多个待查找的元素时,观察寻找最左侧元素的位置

若是找到则返回元素位置,若是找不到则返回-1

java">    public static int binarySearchLeftmost(int[] arr, int key) {int i = 0,j = arr.length-1;int candidate = -1; // 记录候选位置while (i <= j) {int m = (i + j) >>> 1;if (key < arr[m]) {j = m - 1;} else if (arr[m] < key) {i = m + 1;}else {// 记录侯选位置candidate = m;j = m-1;}}return candidate;}

2.找到重复元素中最右侧第一个出现元素的位置

当数组中存在多个待查找的元素时,观察寻找最右侧元素的位置

若是找到则返回元素位置,若是找不到则返回-1

java">    // 重复元素中找到最右
public static int binarySearchRightmost(int[] arr, int key) {int i = 0,j = arr.length-1;int candidate = -1;while (i <= j) {int m = (i + j) >>> 1;if (key < arr[m]) {j = m - 1;}else if (arr[m] < key) {i = m + 1;}else {candidate = m;i = m + 1;}}return candidate;
}

3.返回值的优化——返回插入位置

① 最左侧查找优化

当数组中存在多个待查找的元素时,观察寻找最左侧元素的位置

若是找到则返回元素位置,若是找不到则返回插入时的插入位置

java">    public static int binarySearchLeftmost(int[] arr, int key) {int i = 0,j = arr.length-1;while (i <= j) {int m = (i + j) >>> 1;if (key <= arr[m]) {// 记录侯选位置j = m - 1;} else {// 记录侯选位置i = m + 1;}}// i代表的是 > target目标值的最左侧索引位置return i;}

② 最右侧查找优化

当数组中存在多个待查找的元素时,观察寻找最右侧元素的位置

若是找到则返回元素位置,若是找不到则返回插入时的插入位置

java">    // 重复元素中找到最右public static int binarySearchRightmost(int[] arr, int key) {int i = 0,j = arr.length-1;while (i <= j) {int m = (i + j) >>> 1;if (key < arr[m]) {j = m - 1;}else {i = m + 1;}}// i - 1表示小于等于目标并且最靠近右边的索引位置return i - 1;}

③ 测试

java">    public static void main(String[] args) {int[] arr = {1,2,4,5,6,7,9};System.out.println(binarySearchLeftmost(arr,3));System.out.println(binarySearchRightmost(arr,8));System.out.println(binarySearchLeftmost(arr,4));System.out.println(binarySearchRightmost(arr,5));}

三、最左查询和最右查询的应用

二分查找 Leftmost
        Params:a-待查找的升序数组

                        target-待查找的目标值

        Returns:
                        返回 ≥ target 的最靠左索引

二分查找 Rightmost

        Params:a-待查找的升序数组

                        target-待查找的目标值
        Returns:

                        返回 ≤target 的最靠右索引

1.应用1——求前任

        求前任:Leftmost(查找元素) - 1

        求后任:Rightmost(查找元素) + 1

2.应用2——求排名

        数组内已有元素:Leftmost(排名元素) + 1

        数组内不存在元素:Leftmost(后任元素) 

3.应用3——最近邻居

        求出前后任距离,进行比较,取较小值

4.应用4——范围查询


http://www.ppmy.cn/devtools/104172.html

相关文章

Java经典框架之MyBatis

一、基本介绍 MyBatis 是一个非常流行的 Java 持久层框架&#xff0c;它提供了简单的方法来处理数据库中的数据。MyBatis 可以看作是 JDBC 的一个薄封装&#xff0c;它简化了 JDBC 代码的编写&#xff0c;同时提供了强大的功能&#xff0c;如动态 SQL、映射自定义对象到数据库记…

【PLL】为什么 环路带宽是参考频率的1/10

原因 由于PLL离散时间特性&#xff0c;考虑锁相环的稳定性&#xff0c;环路带宽受到限制&#xff0c;最多为参考频率的1/20~1/10 鉴相器会定时进行对 参考输入和分频器输出之间的相位差进行比较因此&#xff0c;鉴相器是一个在参考频率下工作的离散时间模块这意味着环路带宽被限…

【栈】| 力扣高频题: 基本计算器二

&#x1f397;️ 主页&#xff1a;小夜时雨 &#x1f397;️专栏&#xff1a;算法题 &#x1f397;️如何活着&#xff0c;是我找寻的方向 目录 1. 题目解析2. 代码 1. 题目解析 题目链接: https://leetcode.cn/problems/basic-calculator-ii/description/ (可点击) 本道题是栈…

日常刷题(24)

1. 拼接最大数 1.1. 题目描述 给你两个整数数组 nums1 和 nums2&#xff0c;它们的长度分别为 m 和 n。数组 nums1 和 nums2 分别代表两个数各位上的数字。同时你也会得到一个整数 k。 请你利用这两个数组中的数字中创建一个长度为 k < m n 的最大数&#xff0c;在这个必…

力扣1425.带限制的子序列和

力扣1425.带限制的子序列和 单调队列优化dp f[i] 表示在数组的前 i 个数中进行选择&#xff0c;并且恰好选择了第 i 个数&#xff0c;可以得到的最大和状态转移&#xff1a;f[i] max(max(f[j]) , 0) nums[i];单调队列优化&#xff1a;储存前K个f[i]&#xff0c;并且单调&…

HarmonyOS应用开发者基础认证 | <HarmonyOS第一课>习题-ArkTS语法

1. 下面示例中会导致编译报错的有&#xff1f; A. let x: number null&#xff1b; B. let x: number | null null&#xff1b; C. let y: string null&#xff1b; D. let y: string 100&#xff1b; 看来GPT对这种标准概念选择&#xff0c;也没有统一的说法。 文心一…

MATLAB发票识别系统

课题介绍 该课题为基于MATLAB的发票识别系统。主要识别发票的编号。可定做发票的日期&#xff0c;金额等字段的识别。通过输入图片&#xff0c;校正&#xff0c;定位目标区域&#xff0c;分割&#xff0c;字符分割&#xff0c;模板匹配识别&#xff0c;得出结果。整个设计包含…

数据结构:树形结构(树、堆)详解

数据结构&#xff1a;树形结构&#xff08;树、堆&#xff09;详解 一、树&#xff08;一&#xff09;树的性质&#xff08;二&#xff09;树的种类二叉树多叉树满N叉树完全N叉树 &#xff08;三&#xff09;二叉树的实现1、二叉树结构定义2、二叉树功能实现&#xff08;1&…