基础数据结构——二分算法及时间复杂度

news2024/9/20 8:10:19

这个算法的前提是,数组是升序排列的

算法描述:

i和j是指针可以表示查找范围

m为中间值

当目标值targat比m大时,设置查找范围在m右边:i =m-1

当目标值targat比m小时,设置查找范围在m左边:j =m+1

当targat的值等于m时,返回m的下标

如果最终没找到就返回-1;

算法实现:

public  int  birthDay(int[] a,int target){
    int i=0;
    int j=a.length-1;
    while(i<=j){
        int m= (i+j)/2;
        if(a[m]<target){
            //                目标值在右边
            i= m-1;
        } else if (target<a[m]) {
            //                目标值在左边
            j = m - 1;

        }else if (a[m] == target){
            //找到
            return m;
        }
    }
    return -1;
}

public static void main(String[] args) {

    int targat=4;
    a1 a1= new  a1();
    int a[]= new int[]{2,4,6,8,9};
    int num=a1.birthDay(a,targat);
    System.out.println(num);
}

问题一:为什么是i<=j ,而不是i<j?

因为i 和 j 指向的元素也会参与比较

问题二:(i+j)/2有没有问题?

在 Java 中,表达式 int a = (i + j) / 2 的结果是向下取整。整数除法会丢弃小数部分 。但是如果遇到非常大的数字呢?

Integer.MAX_VALUE2147483647,即 int 类型能够表示的最大值。

当第一次计算时:i + j 结果是 0 + 2147483647 = 2147483647

当第二次计算时:i = 1073741824j = 2147483647

i + j 结果是 1073741824 + 2147483647 = 3221225471

3221225471这个数字超过了整型能够表示的最大值,所以变成了负数:

public static void main(String[] args) {
    int i= 0;
    int j=Integer.MAX_VALUE;
    int m=(i+j)/2;
    System.out.println(m);
    System.out.println("————————————————————————————————————————————");

    i= m+1;  //结果在右边
    m= (i+j)/2;
    System.out.println(m);
}

>>>移位运算符解决:

>>>将二进制数的每一位向右移动一位,丢弃最右边的位,同时在最左边填充零。

使得结果变为正整数

2^7 ------> 2^6 就可以代替/2

例如:

1001 =9

移位后:

0100 = 4

int类型范围解释:

在 32 位带符号整数中,最高位是符号位,0 表示正数,1 表示负数。

剩下的 31 位用于表示数值。

int整型数据类型有32位,因此,数据的范围不带符号可表示为【0,2^32】;

数据的范围带符号可表示为【-2^31,2^31-1】,那么这里我们为什么要减一呢?因为带符号时,一个符号占位也是一位byte。

那负数为啥不-1????

Java 的 int 类型范围是从 -2^312^31 - 1

是求补码的步骤:

  1. 确定原码:首先,写出整数的原码(即正数的二进制表示)。
  2. 取反:将原码中的每一位取反(0 变 1,1 变 0)。
  3. 加一:在取反后的结果上加 1,得到补码。

线性查找代码:

找到返回索引,找不到返回-1

这个和二分法比起来明明这个线性查找代码更加简洁明了,为什么要使用二分法呢?

    public  int LinearSearch(int[] a, int target){
        for (int i = 0; i<a.length;i++){
            if(a[i]==target){
                return i;
            }
        }
        return -1;
    }
}

事前分析法:

因为每个人电脑配置都不一样,所以运行时间是不一样的,所以运行时间不能评判算法的好坏,所以我们需要在运行前分析一下算法。

线性查找代码分析:

1.最差执行情况

2.假设每行语句的执行时间一样

当元素个数是n时:

最坏情况是查找到最后都没找到,所以 最坏情况return i;语句执行0次

数据元素个数n

执行次数

int i = 0;

1

i<a.length;

n+1

i++

n

a[i]==target

n

return -1;

1

    public  int LinearSearch(int[] a, int target){
        for (int i = 0; i<a.length;i++){
            if(a[i]==target){
                return i;
            }
        }
        return -1;
    }
}

语句执行总次数:3n+3

二分法代码分析:

最差情况:查找范围在右侧,并且没找到

当元素个数是n时:

已经确定的执行语句和次数:

int i=0; 1

int j=a.length-1; 1

return -1; 1

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

eg: target=9 [2,3,4,5] 查找次数为 3 也就是说while循环执行了三次

不能得出整数,就向下取整

eg:log2(7)=2.x 就等于2

元素个数

循环次数

4-7

3

floor(log_2(4)) =2 +1

8-15

4

floor(log_2(8)) =3 +1

16-31

5

floor(log_2(16)) =4 +1

32-63

6

floor(log_2(32)) =5 +1

得出规律:n为元素个数

循环次数L:floor(log_2(n)) +1

循环语句:

循环次数

i<=j

L+1

int m= (i+j) >>> 1;

L

a[m]<target

L

target<a[m]

L

j = m - 1;

L

语句执行总次数:5L+4

(floor(log_2(n)) +1 )*5 + 4

化简一下:f(n)=5*log_2(n)+9

对比图象发现:当数据量大的时候还是二分法的执行次数少

时间复杂度O

抛开硬件软件,只考虑算法本身

如何表示时间复杂度??

  • 线性查找算法的函数:fn=3*n+3
  • 二分查找算法的函数:fn=floor(log_2(n))*5 +4

因为我们得出的这两个函数比较复杂,不能让人一眼就看出,所以我们要对fn进行化简,找到一个与它变化趋势相近的表示法

这里:

  • c1代表一个常数
  • f(n)时实际执行代码行数与n的函数
  • g(n)经过花间,变化趋势与f(n)一致的函数

渐进上界:g(n)代表的是最差的一种情况

例一:

  • fn = 3*n+3
  • gn = n
  • 取c=4,在n=3之后,gn可以作为渐进上界,因此表示写法为O(n)

例二:

  • fn=(floor(log_2(n)) +1 )*5 + 4
  • 化简后fn=5*floor(log_2(n)) +9
  • gn = log_2(n)
  • O( log_2(n))

已知f(n),求g(n)

  • 表达式中相乘的常量可以省略: fn = 3*n+3省略 3
  • 多项式中数量规模更小的表达式(低次项): fn = n³+n² 中的n² 因为n²的变化远小于n³
  • 不同底数的对数

渐进下界和渐进紧界:

渐进下界:最优情况 Ω欧米噶

渐进紧界:两种情况都能代表 theta

时间复杂度从低到高:

对应颜色:

空间复杂度:

用O表示:衡量一个算法,随着数据规模的增大,占用的额外空间成本

  • 固定部分:与输入规模无关的内存空间,如固定数量的变量、常量、常数空间等。
  • 可变部分:随着输入规模变化而变化的内存空间,如动态分配的数组、递归调用栈空间等。

二分查找:

需要常数个指针i,j,m,因此额外占用的空间是O(1)

public  int  birthDay(int[] a,int target){
    int i=0;
    int j=a.length-1;
    while(i<=j){
        int m= (i+j)/2;
        if(a[m]<target){
            i= m-1;
        } else if (target<a[m]) {
            j = m - 1;

        }else if (a[m] == target){
            return m;
        }
    }
    return -1;
}

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

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

相关文章

ISO 26262中的失效率计算:IEC 61709-Clause 10_Resistors and resistor networks

目录 概要 1 元器件分类和基准温度 2 失效率的计算 2.1 失效率预测模型 2.2 温度应力系数 2.2.1 温度应力系数计算模型 3.2.2 温度应力系数计算 结语 概要 IEC 61709是国际电工委员会&#xff08;IEC&#xff09;制定的一个标准&#xff0c;即“电子元器件 可靠性 失效…

STM32学习记录-02-GPIO通用输入输出口

mm 1 GPIO简介 GPIO&#xff08;General Purpose Input Output&#xff09;通用输入输出口 可配置为8种输入输出模式 引脚电平&#xff1a;0V~3.3V&#xff0c;部分引脚可容忍5V 输出模式下可控制端口输出高低电平&#xff0c;用以驱动LED、控制蜂鸣器、模拟通信协议输出时…

揭秘GPT-5,探索未来人工智能的无限可能

引言 在过去的几年里&#xff0c;人工智能领域的快速发展引发了全球范围内的广泛关注和讨论。作为这一浪潮的先锋&#xff0c;OpenAI 推出的 GPT 系列模型已经成为了生成式人工智能的代名词。随着 GPT-4 的发布&#xff0c;它在各种任务中表现出的强大能力进一步巩固了其在行业…

精通推荐算法27:行为序列建模之BST— 代码实现

1 引言 上文 精通推荐算法26&#xff1a;行为序列建模之BST— Transformer建模用户行为序列-CSDN博客 讲解了BST的背景和模型结构&#xff0c;本文给出其代码实现&#xff0c;供大家参考。 2 BST核心代码 Transformer已经成为了算法工程师的必备技能&#xff0c;因此这一节给…

文档在线翻译软件推荐哪些?亲测好用的文档翻译器分享

处暑已至&#xff0c;秋风送爽&#xff0c;正是学习交流的好时节。想象一下&#xff0c;在翻阅外文文献或是与国际友人交流时&#xff0c;如果能有一款便捷的文档翻译软件免费版在手&#xff0c;是不是能让学习之路更加畅通无阻呢&#xff1f; 为了方便大家能够有更高效的学习…

UltraISO刻录Ubuntu镜像制作安装U盘

使用UltraISO 软件来刻录Ubuntu镜像启动盘&#xff1a; 首先下载UltraISO软件&#xff0c;然后点击试用&#xff0c;使用RAW的方式刻录就行&#xff01;&#xff01;&#xff01;

【java】RuoYi-Vue前后端分离版本-登陆请求流程解析

【java】RuoYiBootstrap多模块版本-登陆请求流程解析 这里它用到了一个安全管理框架Spring Security 你可以通过这篇文章《Spring Security 详解》 去了解它&#xff0c;怎么使用 登陆请求流程逻辑图 Created with Raphal 2.3.0 &#xff08;1&#xff09;开始 &#xff08;2&a…

基于yolov5猫狗检测

项目简介 该项目使用YOLOv5深度学习框架来检测图像或视频中的猫和狗。YOLOv5&#xff08;You Only Look Once v5&#xff09;是一种高效的物体检测模型&#xff0c;能够快速准确地识别出图像中的目标。本项目具有以下特点&#xff1a; 图像检测&#xff1a;用户可以通过上传图…

Nginx-企业高性能web服务器 超长完整版!只有你想不到 没有你学不到的满满干货!!

Web服务基础介绍 Web 服务器访问流程 按下回车时浏览器根据输入的 URL 地址发送请求报文给服务器。服务器接收到请求报文&#xff0c;会对请求报文进行处理。服务器将处理完的结果通过响应报文返回给浏览器。浏览器解析服务器返回的结果&#xff0c;将结果显示出来。 1. 输入…

苹果手机视频误删怎么恢复?看完拍手叫好的4个方法

试想一下&#xff0c;当你在翻看苹果手机相册的视频&#xff0c;正沉浸在过往的美好回忆中时&#xff0c;手指一不小心触碰到了屏幕上的删除按钮&#xff0c;手机上的视频就这样消失了……面对这样的意外情况&#xff0c;苹果手机视频误删怎么恢复呢&#xff1f;别急&#xff0…

Nuxt学习_基础知识(一)

文章学习来源&#xff0c;nuxt中文网 1. 安装nuxt 指令 npx create-nuxt-app t_nuxt或yarn create nuxt-app f_nuxt 执行指令后按需选择添加自己所需要的相关依赖&#xff0c;若安装出现报错等问题 清除npm、yarn缓存 npm cache clean --force yarn cache clean切换安装命令切…

NSIS - 创建桌面应用程序(Client-Side, CS 或者称为本地应用程序)的安装包

B站视频 C# winform Costura.Fody将多个dll打包生成一个可执行的exe文件中_哔哩哔哩_bilibili 博客 NSIS打包教程 Wnform程序打包-罗分明网络博客 补充:(以下面代码为例) ; 该脚本使用 HM VNISEdit 脚本编辑器向导产生; 安装程序初始定义常量 !define PRODUCT_NAME "sql…

9个超强查找下载化学学科文献的数据库 建议收藏

一、CAS&#xff08;美国化学文摘社&#xff09;数据库 CAS SciFinder Discovery Platform 是由全球科学信息引领者CAS&#xff08;美国化学文摘社&#xff09;出品的新一代的权威科学研究工具&#xff0c;是化学及相关学科智能研究平台&#xff0c;提供全球全面、可靠的化学及…

图片转PDF?小case!这几步操作,让你秒变职场小旋风

嘿&#xff0c;大家在忙碌的工作里&#xff0c;经常得处理一堆文件和照片&#xff0c;尤其是当你想把一堆照片弄成一个PDF文件时&#xff0c;这事儿就显得特别重要。不管是为了做报告、提项目建议还是整理日常工作资料&#xff0c;把照片转成PDF格式&#xff0c;都能让我们工作…

知识付费小程序引领线上直播

亲爱的朋友们&#xff0c;欢迎来到“探索未知领域&#xff0c;知识付费小程序引领知识新探索”线上直播课程&#xff01; 在这个信息爆炸的时代&#xff0c;知识的获取从未如此便捷&#xff0c;但高质量、有深度的知识却仍需我们精心筛选。本次直播课程&#xff0c;将聚焦于知识…

conda切换32位运行环境,解决无法在64位系统中安装32位py

当前系统大部分都64位的&#xff0c;我的conda也是64位的&#xff0c;但是如果需要创建32位的py环境&#xff0c;会发现 conda create -n DouyinLive32 python3.7 --force创建的仍然是32位的&#xff0c;为此我们可以使用切换命令切换。 按一下Windows键&#xff0c;输入Prom…

大数据-94 Spark 集群 SQL DataFrame DataSet RDD 创建与相互转换 SparkSQL

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

数据资产入表,全流程实施指南!

数据成为生产要素已是社会共识&#xff0c;但不是所有数据都有资产价值。数据资源当中被重复使用的那部分才会资产化&#xff0c;具有流通中的定价&#xff0c;有些数据资产被专业开发变成数据产品&#xff0c;具有商品价值。从数据原始资源到数据产品&#xff0c;再到数据资产…

华为LTC流程体系的内涵(附PPT分享)

往期回顾&#xff1a; 企业4A架构&#xff1a;数字化转型的底层方法论&#xff08;附TOGAF资料下载&#xff09; PPT分享&#xff1a;数据治理的方法论、设计思路与方案&#xff08;干货&#xff09; 浅谈数字化转型方法论 110页PPT:xx业务流程优化&#xff08;BPR&#xff…

Linux压缩和解压

目录 压缩和解压类 gzip/gunzip指令 zip/unzip指令 tar指令 压缩和解压类 gzip/gunzip指令 gzip用于压缩文件&#xff0c;gunzip用于解压缩文件。 解压后去掉了gz的后缀。 zip/unzip指令 ​​​​​​​ 将文件压缩后发给别人&#xff0c;别人再解压。 将整个文件压…