当前位置: 首页 > article >正文

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

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

                                                                                                —— 24.8.31

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

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

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

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

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

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:绝对值函数
            // 插入点索引insert
            int insert = Math.abs(res+1);
            // 创建数组B
            int[] 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

    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

    // 重复元素中找到最右
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.返回值的优化——返回插入位置

① 最左侧查找优化

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

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

    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;
    }

② 最右侧查找优化

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

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

    // 重复元素中找到最右
    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;
    }

③ 测试

    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.kler.cn/a/284700.html

相关文章:

  • 如何使用 Web Scraper API 高效采集 Facebook 用户帖子信息
  • RabbitMQ高效的消息队列中间件原理及实践
  • Docker 篇-Docker 详细安装、了解和使用 Docker 核心功能(数据卷、自定义镜像 Dockerfile、网络)
  • 华为机试HJ39 判断两个IP是否属于同一子网
  • Wireshark
  • jenkins提交gitee后自动部署
  • 激光雷达定位算法在FPGA中的实现——section2 全局坐标和角度计算
  • 小程序全局挂载对像
  • SQL经典五十道选刷
  • ffmpeg各模块常用组件源码位置
  • C++(1)基础语法
  • 【3.6】贪心算法-解救生艇问题
  • 目标检测之困难目标检测任务综述
  • SpringBoot异常处理原理分析
  • JMeter 工具安装以及简单使用
  • 人工智能再次进化 善用AI提升营运效率
  • 力扣234题详解:回文链表的多种解法与模拟面试问答
  • scrapy学习笔记0828-下
  • 《自然语言处理》—— 词向量之CountVectorizer方法实现
  • raksmart机云大宽带服务器托管服务内容
  • 安防视频汇聚平台EasyCVR启动后无法访问登录页面是什么原因?
  • PhpStorm2024版设置自动换行(软换行)
  • 2024.8.31 Python,合并区间,用sort通过列表第一个元素给列表排序,三数之和,跳跃游戏
  • AcWing 897. 最长公共子序列
  • JVM 内存参数
  • JetBrains WebStorm 2024.2 (macOS, Linux, Windows) - 最智能的 JavaScript IDE