数据结构与算法——Java实现 1.初识算法 —— 二分查找

news2024/12/23 9:21:57

目录

一、线性查找

二、二分查找

基础版

问题1 —— 循环条件

问题2 —— i+j/2有没有问题

问题3 —— 代码中都写成 < 有何好处

改动版


人生的意义就是要独自穿过悲喜

                                —— 24.8.27

需求:在有序数组A内,查找值 target,如果找到返回索引,如果找不到返回 -1

一、线性查找

待查找的数组,可以不是有序数组

    // 线性查找法
    public static int StrFind(int target,int[] arr){
        for(int i=0;i<arr.length;i++){
            if(arr[i]==target){
                return i;
            }
        }
        return -1;
    }

二、二分查找

待查找的数组必须是升序数组

1.基础版

问题1 —— 循环条件

为什么在写while循环时,条件为i<=j而不是i<j

因为会省略i=j时的元素

问题2 —— (i+j) / 2有没有问题

为避免(两个大数相加,将第一位当作符号位,最终得出负数)数值过大,大于整数最大值后,除2得不到正确的答案,所以改为无符号右移,也可以适用于更多的语言

问题3 —— 代码中都写成 < 有何好处

因为数组中是升序排列,比较别扭,其他同理

    // 二分查找基础版
    public static int BS(int target,int[] arr){
        int i = 0, j = arr.length-1;
        while(i <= j){
            // 为避免(两个大数相加,将第一位当作符号位,最终得出负数)数值过大,大于整数最大值后,除2得不到正确的答案,所以改为无符号右移,也可以适用于更多的语言
            // int mid = (i+j)/2;
            int mid = (i+j) >>> 1;
            if(arr[mid]==target){
                return mid;
            }else if(arr[mid]<target){
                i = mid+1;
            }else {
                j = mid-1;
            }
        }
        return -1;
    }
public class demo1BinarySearch {
    // 线性查找法
    public static int StrFind(int target,int[] arr){
        for(int i=0;i<arr.length;i++){
            if(arr[i]==target){
                return i;
            }
        }
        return -1;
    }

    // 二分查找基础版
    public static int BS(int target,int[] arr){
        int i = 0, j = arr.length-1;
        while(i <= j){
            // 为避免(两个大数相加,将第一位当作符号位,最终得出负数)数值过大,大于整数最大值后,除2得不到正确的答案,所以改为无符号右移,也可以适用于更多的语言
            // int mid = (i+j)/2;
            int mid = (i+j) >>> 1;
            if(arr[mid]==target){
                return mid;
            }else if(arr[mid]<target){
                i = mid+1;  // 目标值在右边
            }else {
                j = mid-1;  // 目标值在左边
            }
        }
        return -1;
    }

    public static void main(String[] args) {
        int[] arr = {7,12,19,27,35,42,43,44};
        int target1 = 30;
        int target2 = 43;
        int res1 = StrFind(target1,arr);
        System.out.println("res1 = "+res1);
        int res2 = BS(target2,arr);
        System.out.println("res2 = "+res2);
        int res3 = BS(19,arr);
        System.out.println("res3 = "+res3);
    }
}

2.改动版

为避免当数组中存在趋于中间位置,却又不存在的查找数,进行的三处改动

    // 二分查找改动版
    public static int binarySearch2(int[] arr, int target) {
        int i = 0, j = arr.length;  // 第一处改动
        while (i < j) {     // 第二处改动
            int mid = (i+j) >>> 1;
            if (arr[mid] == target) {
                return mid;
            }else if(arr[mid] < target) {
                i = mid + 1;
            }else {
                j = mid;    // 第三处改动
            }
        }
        return -1;
    }

3.平衡版

① 左闭右开的区间,i指向的可能是目标,而ì指向的不是目标

② 不在循环内找出,等范围内只剩ì时,退出循环,在循环外比较 a[i] 与 target

③ 循环内的平均比较次数减少了

④ 时间复杂度 O(log(n))

    // 二分查找平衡版
    public static int binarySearch3(int[] arr, int target) {
        int i = 0, j = arr.length;
        while (1 < j - i) {
            int mid = (i + j) >>> 1;
            if (target < arr[mid]) {
                j = mid;
            }else{
                i = mid;
            }
        }
        if (arr[i] == target) {
            return i;
        }else{
            return -1;
        }
    }
package Day1;

public class demo1BinarySearch {
    // 线性查找法
    public static int StrFind(int target,int[] arr){
        for(int i=0;i<arr.length;i++){
            if(arr[i]==target){
                return i;
            }
        }
        return -1;
    }

    // 二分查找基础版
    public static int BS(int target,int[] arr){
        int i = 0, j = arr.length-1;
        while(i <= j){
            // 为避免(两个大数相加,将第一位当作符号位,最终得出负数)数值过大,大于整数最大值后,除2得不到正确的答案,所以改为无符号右移,也可以适用于更多的语言
            // int mid = (i+j)/2;
            int mid = (i+j) >>> 1;
            if(arr[mid]==target){
                return mid;
            }else if(arr[mid]<target){
                i = mid+1;  // 目标值在右边
            }else {
                j = mid-1;  // 目标值在左边
            }
        }
        return -1;
    }

    // 二分查找改动版
    public static int binarySearch2(int[] arr, int target) {
        int i = 0, j = arr.length;  // 第一处改动
        while (i < j) {     // 第二处改动
            int mid = (i+j) >>> 1;
            if (arr[mid] == target) {
                return mid;
            }else if(arr[mid] < target) {
                i = mid + 1;
            }else {
                j = mid;    // 第三处改动
            }
        }
        return -1;
    }

    // 二分查找平衡版
    public static int binarySearch3(int[] arr, int target) {
        int i = 0, j = arr.length;
        while (1 < j - i) {
            int mid = (i + j) >>> 1;
            if (target < arr[mid]) {
                j = mid;
            }else{
                i = mid;
            }
        }
        if (arr[i] == target) {
            return i;
        }else{
            return -1;
        }
    }

    public static void main(String[] args) {
        int[] arr = {7,12,19,27,35,42,43,44};
        int target1 = 30;
        int target2 = 43;
        int res1 = StrFind(target1,arr);
        System.out.println("res1 = "+res1);
        int res2 = BS(target2,arr);
        System.out.println("res2 = "+res2);
        int res3 = BS(19,arr);
        System.out.println("res3 = "+res3);
        int res4 = binarySearch2(arr,27);
        System.out.println("res4 = "+res4);
        int res5 = binarySearch3(arr,35);
        System.out.println("res5 = "+res5);
    }
}

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

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

相关文章

小鹏在这次发布会上有哪些黑科技呢?

在今晚举办的小鹏10年热爱之夜&小鹏MONA MO3上市发布会上&#xff0c;何小鹏宣布&#xff0c;小鹏自研图灵芯片已于8月23日流片成功。据介绍&#xff0c;小鹏图灵芯片是全球首颗同时应用在AI汽车、机器人、飞行汽车的AI芯片&#xff0c;为AI大模型定制。 该芯片采用40核心…

【STM32】时钟体系

一、时钟体系 为什么需要时钟&#xff1f; 时钟可以为系统提供精确的定时&#xff0c;比如时间显示&#xff0c;定时器&#xff0c;pwm… 为芯片各功能模块提供工作势能,使能各组管脚工作&#xff0c;如果不使能&#xff0c;管脚无法工作 同步数据传输 给单片机提供一个时…

RabbitMQ中的死信交换机?(RabbitMQ延迟队列有了解过吗)

延迟队列 延迟队列:进入队列的消息会被延迟消费的队列。 延迟队列死信交换机 TTL&#xff08;过期时间&#xff09; 延迟队列的使用场景:超时订单、限时优惠、定时发布 死信交换机 当一个队列中的消息满足下列情况之一时&#xff0c;可以成为死信(dead letter): 消费者使…

探讨Vision Pro的成本优化与设计改进之路

随着Apple Vision Pro的发布,这款革命性的头戴式显示设备凭借其创新技术和用户体验吸引了大量关注。然而,高昂的价格成为了一个不可忽视的问题,阻碍了它的普及。为了让更多消费者能够负担得起这款产品,Apple需要探索各种方法来降低成本而不牺牲用户体验。本文将总结一些关于…

医用双目放大镜行业分析:前五大厂商占有大约39.0%的市场份额

一、当前市场状况 1. 市场规模与增长趋势 - 目前医用双目放大镜市场呈现出稳定增长的态势。据报告显示&#xff0c;预计到 2030 年全球市场规模将达到 5.2 亿美元&#xff0c;年复合增长率为 7.8%&#xff0c;这表明该行业具有较大的发展潜力。 - 增长的动力主要来自医疗行业…

排序算法(冒泡、插入、选择、快排、归并)原理动画及Python、Java实现

排序算法&#xff08;冒泡、插入、选择、快排、归并&#xff09;原理动画及Python、Java实现 1 冒泡排序1.1 原理1.2 Python、Java实现 2 插入排序2.1 原理2.2 Python、Java实现 3 选择排序3.1 原理3.2 Python、Java实现 4 快速排序4.1 原理4.2 Python、Java实现 5 归并排序5.1…

【机器学习】独立成分分析的基本概念、应用领域、具体实例(含python代码)以及ICA和PCA的联系和区别

引言 独立成分分析&#xff08;Independent Component Analysis&#xff0c;简称ICA&#xff09;是一种统计方法&#xff0c;用于从多个观察到的混合信号中提取出原始的独立信号源 文章目录 引言一、独立成分分析1.1 定义1.2 独立成分分析的基本原理1.3 独立成分分析的步骤1.3.…

RASA使用长文记录以及一些bug整理

RASA 学习笔记整理 一 安装 在虚拟环境中安装&#xff0c;进入python3版本的环境 conda activate python3 ai04机器旧版本&#xff1a;rasa-nlu和rasa-core是分开安装的 最新版本&#xff1a;rasa 将二者做了合并 直接安装 pip3 install rasa 在安装到如下步骤时候会报…

读软件开发安全之道:概念、设计与实施11安全地编程

1. 安全地编程 1.1. 在一个完整的软件设计过程中&#xff0c;我们要在创建和审查时就将安全性放在心中&#xff0c;但这只是产品开发过程的开始&#xff0c;接下来是实现、测试、部署、运行、监控、维护&#xff0c;并最终在生命周期结束时将其淘汰 1.2. 开发人员不仅必须忠实…

Android Launcher启动过程

## Launcher的启动流程&#xff1a; 1.Zygote进程 –> SystemServer进程 –> startOtherService方法 –> ActivityManagerService的systemReady方法 –> startHomeActivityLocked方法 –> ActivityStackSupervisor的startHomeActivity方法 –> 执行Activity…

Java | Leetcode Java题解之第380题O(1)时间插入、删除和获取随机元素

题目&#xff1a; 题解&#xff1a; class RandomizedSet {List<Integer> nums;Map<Integer, Integer> indices;Random random;public RandomizedSet() {nums new ArrayList<Integer>();indices new HashMap<Integer, Integer>();random new Rando…

Java9模块化系统JPMS(Java Platform Module System)

引言 随着Java技术的发展&#xff0c;开发人员面临的挑战之一是如何有效地管理和组织大型项目的依赖关系。传统的类路径&#xff08;classpath&#xff09;方法虽然简单&#xff0c;但在大型项目中却难以管理&#xff0c;尤其是在面对复杂的依赖关系时。为了解决这些问题&…

Kafka入门:从零开始了解分布式流处理平台

什么是Kafka Apache Kafka是由LinkedIn公司开发&#xff0c;后来由Apache软件基金会维护的一个分布式、分区、多副本的基于ZooKeeper协调的分布式消息系统。Kafka不仅是一个消息队列&#xff0c;还是一个强大的流处理平台&#xff0c;它能够实时地处理大量数据&#xff0c;满足…

Springboot如何实现redis消息的订阅发布

1. 环境准备 确保你已经安装了 Redis 服务器&#xff0c;并且可以在本地或者远程访问它。如果你还没有安装 Redis&#xff0c;请先安装并启动 Redis 服务。 2. 创建 Spring Boot 项目 使用 Spring Initializr 或者其他 IDE 创建一个新的 Spring Boot 项目&#xff0c;并添加以下…

Leetcode 1047-删除字符串中的所有相邻重复项

给出由小写字母组成的字符串 S&#xff0c;重复项删除操作会选择两个相邻且相同的字母&#xff0c;并删除它们。 在 S 上反复执行重复项删除操作&#xff0c;直到无法继续删除。 在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。 题解 题目链接 //先进后出&a…

cubeide Target is not responding, retrying... 或基于vscode方式等 无法调试

点击调试输出如图&#xff1a; 基于cubeidet开发环境&#xff0c;debug后输出&#xff1a; 基于vscode开发环境&#xff1a; OpenOCD: GDB Server Quit Unexpectedly. See gdb-server output in TERMINAL tab for more details. 解决方法&#xff1a; 这里的调试选择一个&…

Vue3源码调试-第二篇

前言 上篇我们见到一个很厉害的方法&#xff0c;这篇我们来看看 baseCreateRenderer 首先&#xff0c;方法太多了&#xff0c;我也不一个一个数有多少个了&#xff0c;因为我们着重使用createApp方法&#xff0c;那么我们就跟着代码走&#xff0c;用到哪个方法就分析哪个方法…

vue的for循环不建议用index作为key

我们页面总有一些相似的&#xff0c;我们想用循环渲染&#xff0c;根据对象数组结构进行渲染&#xff0c;这是不是很熟悉的场景。这时候我们需要有一个唯一的key绑定在循环渲染的元素上&#xff0c;一般情况下我们会用id&#xff0c;因为id是唯一的。然而有些页面要循环的数据&…

python 把一个视频复制3次

1. 先看效果 输入 输出 2. 代码 第一种方法 moviepy 代码来源 gpt4o from moviepy.editor import VideoFileClip, clips_array# 加载视频 video VideoFileClip("a22.mp4")# 复制视频三次 video_copied clips_array([[video, video, video]])# 输出最终的视频 vi…

关于tresos Studio(EB)的MCAL配置之ADC

General Adc_DeInit API 使能Adc_DeInit接口 Adc Development Error Detection 开发者错误检测 Adc Enable Limit Check边界检测 Adc Queue启用队列&#xff0c;如果AdcPriorityImplementationADC_PRIORITY_HW_SW执行优先级为硬件则一定要开启队列 Adc_StartStopGroup API使…