【算法】二分查找算法——leetcode二分查找、搜索插入位置

news2025/1/16 1:04:30

文章目录

  • 二分查找
    • 704. 二分查找
    • 35. 搜索插入位置

二分查找

  二分查找算法是一种在有序数组中查找特定元素的搜索算法。算法的工作原理是,通过比较数组中间元素和目标值,如果目标值等于中间元素,那么查找结束。如果目标值小于或大于中间元素,则在数组的前半部分或后半部分进行查找。此过程将一直持续到找到目标值,或者搜索范围为空。

  需要注意的是,二分查找算法只适用于已排序的数组。如果给定的数组是无序的,那么在进行二分查找之前,需要先对数组进行排序。

  以下是一个朴素二分查找算法的步骤:

  (1)选择数组的中间元素。

  (2)如果中间元素正好是要查找的元素,则搜索过程结束。

  (3)如果要查找的元素大于中间元素,则在数组的后半部分进行搜索。

  (4)如果要查找的元素小于中间元素,则在数组的前半部分进行搜索。

             

在这里插入图片描述

704. 二分查找

二分查找

(1)二分查找

  算法思路:(当 right = nums.size()-1 时)

  我们定义 left , right 指针,分别指向数组的左右区间。之后找到待查找区间的中间点 middle ,找到之后分三种情况讨论:

(1)nums[middle] == target 说明正好找到,返回 mid 的值;

(2)nums[middle] > target 说明 [middle, right] 这段区间都是大于 target 的, 因此舍去右边区间,在左边 [left, middle -1] 的区间继续查找,即让 right = middle - 1 ,然后重复 2 过程;

(3)nums[middle] < target 说明 [left, middle] 这段区间的值都是小于 target 的, 因此舍去左边区间,在右边 [middle + 1, right] 区间继续查找,即让 left = middle + 1 ,然后重复 2 过程;

  当 left 与 right 错开时,说明整个区间都没有这个数,返回 -1。

             

  算法实现过程:(当 right = nums.size()-1 时)

  首先,它初始化两个指针,‘left’和’right’,分别指向数组的开始和结束。 然后,它进入一个循环,在循环中,它找到数组中间的元素(‘middle’),并根据这个中间元素和目标值的比较结果来更新搜索范围。

  如果中间元素等于目标值,那么函数就返回中间元素的索引。

  如果中间元素大于目标值,那么目标值必然在数组的左半部分, 所以它将’right’指针移动到’middle - 1’,缩小搜索范围为左半部分。

  否则,目标值必然在数组的右半部分, 所以它将’left’指针移动到’middle + 1’,缩小搜索范围为右半部分。

  如果在数组中没有找到目标值,那么函数返回-1。

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

在这里插入图片描述

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left=0,right=nums.size()-1;
        while(left<=right)//[left right]
        {
            int middle=(right+left)/2;
            if(nums[middle]==target)
            return middle;

            else if(nums[middle]>target)//[left target middle   ...  right]
            right=middle-1;             //[left target right]

            else                        //[left  ...   middle target right]
            left=middle+1;              //[left target right]
        }
        return -1;
    }
};

             

当然right也可以等于nums.size()

  和上面的代码实现基本类似,只是有些条件需要改变。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left=0,right=nums.size();
        while(left<right)//[left right)
        {
            int middle=(right+left)/2;
            if(nums[middle]==target)
            return middle;

            else if(nums[middle]>target)//[left target middle   ...  right)
            right=middle;               //[left target right)

            else                        //[left  ...   middle target right)
            left=middle+1;              //[left target right)
        }
        return -1;
    }
};

在这里插入图片描述

时间复杂度:O(logn)

             

35. 搜索插入位置

搜索插入位置

在这里插入图片描述
             

(1)二分查找

  算法思路:

  (1)设插入位置的坐标为 index , 根据插入位置的特点可以知道:
  [left, index - 1] 内的所有元素均是小于 target 的;
  [index, right] 内的所有元素均是大于等于 target 的。

  (2)设 left 为本轮查询的左边界, right 为本轮查询的右边界。 根据 mid 位置元素的信息,分析下⼀轮查询的区间:
  当 nums[mid] >= target 时,说明 mid 落在了 [index, right] 区间上, mid 左边包括 mid 本身,可能是最终结果,所以我们接下来查找的区间在 [left, mid] 上。因此,更新 right 到 mid 位置,继续查找。
  当 nums[mid] < target 时,说明 mid 落在了 [left, index - 1] 区间上, mid 右边但不包括 mid 本⾝,可能是最终结果,所以我们接下来查找的区间在 [mid +1, right] 上。因此,更新 left 到 mid + 1 的位置,继续查找。

  (3)直到我们的查找区间的长度变为 1 ,也就是 left == right 的时候, left 或者right 所在的位置就是我们要找的结果。

             

  算法实现:

  (1)初始化两个指针,left和right,分别指向数组的开始和结束。

  (2)进入一个while循环,只要left小于right,循环就会继续。 在循环中,首先找到数组中间的元素(mid)。

  (3)如果中间元素小于目标值,那么目标值必然在数组的右半部分,所以将left移动到mid+1,缩小搜索范围为右半部分。

  (4)否则,目标值必然在数组的左半部分或者就是中间元素本身,所以将right移动到mid,缩小搜索范围为左半部分或者就是中间元素。

  (5)当循环结束时,right指向的元素可能是目标值,也可能不是。如果这个元素小于目标值,说明目标值应该插入到数组的右侧,所以返回right+1;否则,返回right。

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int left=0,right=nums.size()-1;
        while(left<right)
        {
            int mid=(left+right)/2;
            if(nums[mid]<target)
            left=mid+1;

            else
            right=mid;
        }
        if(nums[right]<target)//判断target是否大于nums中的最大值
        return right+1;

        return right;
    }
};

在这里插入图片描述

时间复杂度:O(logn)

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

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

相关文章

单元测试界的高富帅,Pytest框架 (三) 用例标记和测试执行篇

pytest用例标记和测试执行篇 上一篇文章入门篇咱们介绍了pytest的前后置方法和fixture机制&#xff0c;这个章节主要给大家介绍pytest中的标记机制和用例执行的方法。pytest可以通过标记将数据传入于测试函数中&#xff0c;也可以通过标记中对执行的用例做筛选&#xff0c;接下…

NTC 温度采样 二分查表及公式法

NTC 温度采样&#xff1a; 本文记录对NTC 温度采样&#xff0c;分别采用二分查表法及公式法进行描述 资源下载链接&#xff1a;Excel 生成数组表 https://download.csdn.net/download/qq_41359157/88326839?spm1001.2014.3001.5503 NTC参数&#xff1a; NTC采样电路&#xf…

2023 年 Vue 最流行的动画库

数字世界以短暂的注意力和激烈的竞争为主导&#xff0c;因此必须立即将受众的注意力吸引到您的网站上。使用 Vue 动画库&#xff0c;您可以毫不费力地实现这一目标。据报道&#xff0c;VueJs 是 JavaScript 类别中第 7 大最受欢迎的&#xff0c;来自世界各地的开发人员使用它来…

arthas基本应用

下载 arthas curl https://arthas.aliyun.com/arthas-boot.jar启动 arthas&#xff08;启动之前确保有一个 java进程服务&#xff09; java -jar arthas-boot.jar输入3&#xff0c;再输入回车/enter。Arthas 会 attach 到目标进程上&#xff0c;并输出志&#xff1a; 输入das…

如何抢占3020亿美元市场先机?送你一份指南

印度电商市场规模正在快速增长。预计到2023年&#xff0c;印度电商市场规模将达到2000亿美元。其中&#xff0c;B2C电商市场规模将占据主导地位&#xff0c;预计将增长至1000亿美元。 此外&#xff0c;印度政府也在积极推动数字化发展&#xff0c;为电商企业提供更多机会。政府…

Python语言:算术运算符知识点讲解

前言&#xff1a;学了几天python&#xff0c;可把我折磨坏了。为什么呢&#xff0c;就是python语言都特别爱空格&#xff0c;我有时候就忘了&#xff0c;就报错了啦。就比如这个&#xff1a;a 8&#xff0c;等于号前面和后面都需要空格&#xff0c;有点不习惯&#xff0c;在慢…

Spring中的事务与事务传播机制

事务 在学习MySQL时我们学习过事务&#xff0c;而到了Spring的学习时&#xff0c;同样会学习到事务&#xff0c;两个东西的事务的定义都是一样的&#xff1a;将一组操作封装成一个执行单元&#xff0c;要么全部成功&#xff0c;要么全部失败 在Spring中使用事务有两种方式 一…

GitHub星标超70K,阿里大佬的架构总结“分布式全解”笔记霸榜

分布式架构与微服务平台是当今IT界的关键技术&#xff0c;也是资深软件工程师和系统架构师必须掌握的核心技术。 因此小编为各位粉丝朋友带来这份阿里大佬的分布式笔记&#xff1a;从传统分布式架构迁移到基于容器技术的微服务架构为主线&#xff0c;全面、透彻地介绍了与分布…

十七、Webpack搭建本地服务器

一、为什么要搭建本地服务器&#xff1f; 目前我们开发的代码&#xff0c;为了运行需要有两个操作&#xff1a; 操作一&#xff1a;npm run build&#xff0c;编译相关的代码&#xff1b;操作二&#xff1a;通过live server或者直接通过浏览器&#xff0c;打开index.html代码…

【业务功能篇106】 微服务-springcloud-springboot-电商订单模块--秒杀服务-定时任务【下篇】

四、秒杀活动 1.秒杀活动关注点 秒杀活动的最大特点就是高并发而且是短时间内的高并发&#xff0c;那么对我们的服务要求就非常高&#xff0c;针对这种情况所产生的共性问题&#xff0c;对应的解决方案&#xff1a; 2. 秒杀服务前端 当我们点击 秒杀抢购按钮后&#xff0c;对应…

【C#-1】C#调用matlab生成的dll库

matlab打包dll 1、matlab示例程序&#xff1a; function untitled4(x)z peaks(x);figuresurf(z) end 2、输入deploytool打包matlab程序&#xff0c;具体如下&#xff1a; 3、拷贝 打包成功后&#xff0c;将生成for_redistribution_files_only文件夹中的dll文件拷贝到C#程序…

【设计模式】三、概述分类+单例模式

文章目录 概述设计模式类型 单例模式饿汉式&#xff08;静态常量&#xff09;饿汉式&#xff08;静态代码块&#xff09;懒汉式(线程不安全)懒汉式(线程安全&#xff0c;同步方法)懒汉式(线程安全&#xff0c;同步代码块)双重检查静态内部类枚举单例模式在 JDK 应用的源码分析 …

Llama2-Chinese项目:1-项目介绍和模型推理

Atom-7B与Llama2间的关系&#xff1a;Atom-7B是基于Llama2进行中文预训练的开源大模型。为什么叫原子呢&#xff1f;因为原子生万物&#xff0c;Llama中文社区希望原子大模型未来可以成为构建AI世界的基础单位。目前社区发布了6个模型&#xff0c;如下所示&#xff1a; FlagAl…

无线振动传感器革新:设备维护的新范式

随着工业界的不断发展和技术的进步&#xff0c;设备维护的方法也在不断演变。过去&#xff0c;维护通常是基于固定的时间表和例行的检查进行的&#xff0c;这种方法往往会导致资源的浪费和不必要的停机时间。然而&#xff0c;现在&#xff0c;随着无线振动传感器的革新&#xf…

【C++】内联函数 ⑤ ( 内联函数总结 | 内联函数代码示例 )

文章目录 一、内联函数总结二、内联函数代码示例1、代码示例 - 普通函数执行分析2、代码示例 - 内联函数执行分析3、代码示例 - 宏代码片段执行分析 一、内联函数总结 回顾下 之前的博客中 介绍的 内联函数 : 内联函数编译 : C 编译器 编译 内联函数 时 , 会直接 将 内联函数 …

前端开发纷繁复杂,是否有更高效的开发方式?

一、前言 此前&#xff0c;我曾跟大家聊到&#xff0c;低代码编程&#xff0c;在现阶段互联网业务疯狂增长的带动之下&#xff0c;被赋予了全新的使命和义务&#xff0c;即帮助开发者在前期以较低成本的方式&#xff0c;快速构建一个可投入市场的应用。 那么&#xff0c;有没有…

腾讯云轻量2核4G5M服务器_CPU内存_流量_带宽_系统盘

腾讯云轻量2核4G5M服务器&#xff1a;CPU内存流量带宽系统盘性能测评&#xff1a;轻量应用服务器2核4G5M带宽&#xff0c;免费500GB月流量&#xff0c;60GB系统盘SSD盘&#xff0c;5M带宽下载速度可达640KB/秒&#xff0c;流量超额按照0.8元每GB支付流量费&#xff0c;轻量2核4…

都2023年了,别再用ifconfig啦! 试试这个吧!

下午好&#xff0c;我的网工朋友。 ifconfig这玩意儿&#xff0c;还有多少人在用&#xff1f;举个手看看 总在说ifconfig即将被淘汰&#xff0c;但其实很多网工还在用吧。 比如说组合使用诸如ifconfig、route、arp和netstat等命令行工具&#xff08;来源于安装包net-tools&a…

调查称全球多所顶尖高校网站存在网络攻击风险

Cyber News的一项调查研究显示&#xff0c;全球多所顶尖高校的网站未能及时更新安全补丁&#xff0c;存在敏感信息泄露&#xff0c;甚至被攻击者全面接管的风险。 Cyber​​ News 研究团队详细调查了 20 个每月有数百万访问量的高校网站&#xff0c;其中至少有6个是位于全球Top…

Mac清理垃圾软软件CleanMyMac X的软件功能介绍

在我们使用我们的Mac一定的时间后&#xff0c;总是不可避免的出现Mac内存不足的情况&#xff0c;所以清理垃圾软件也就成为了我们电脑里必不可少的软件。苹果软件商店中有很多各有不同的清理垃圾软件&#xff0c;但我们往往很难从这一大堆软件中找到令自己心满意足的。 但是这…