LeetCode 704.二分查找

news2025/1/18 21:06:06

LeetCode 704.二分查找

1、题目

题目链接:704. 二分查找
在这里插入图片描述

2、思路

这道题目是要在有序数组 nums 中找到目标值 target,符合二分查找的前提条件(线性表必须是有序的,且采用顺序存储)。同时题目还强调数组中无重复元素(若有重复元素,则使用二分查找法返回的元素下标可能不唯一)。
基于上述条件,这道题可以使用二分查找寻找目标值。
二分查找的做法是,定义查找的范围 [left, right],初始查找范围是整个数组,每次取查找范围的中点 middle,比较 nums[middle] 和 target 的大小,如果相等,则 middle 就是要寻找的下标,如果 nums[middle] > target,则 target 只可能在 middle 的左侧,如果 nums[middle] < target,则 target 在 middle 的右侧。
这样每次查找都会将查找范围缩小一半,因此二分查找的时间复杂度是 O(logn),其中 n 是数组的长度。
二分查找的条件是查找范围不为空,如果 target 在数组中,二分查找可以保证找到 target,返回 target 在数组中的下标。如果 target 不在数组中,则返回 -1。

3、二分法(左闭右闭区间)

代码:

class Solution {
public:
    int search(vector<int>& nums, int target) {
        // 避免当 target 小于 nums[0] 或者 target 大于 nums[nums.size() - 1] 时多次循环运算
        if(nums[0] > target || nums[nums.size() - 1] < target) {
            return -1;
        }
 
        int left = 0;
        int right = nums.size() - 1; // 定义target在左闭右闭的区间里,[left, right]
 
        while(left <= right) { // 当 left == right,区间 [left, right] 依然有效,所以用 <=
            int middle = left + ((right - left) >> 1); // 防止溢出 等同于 (left + right)/2
            if(nums[middle] == target) { // 找到目标值,直接返回下标
                return middle;
            }else if(nums[middle] < target) {
                left = middle + 1; // target 在右区间,所以 [middle + 1, right]
            }else { // nums[middle] > target
                right = middle - 1; // target 在左区间,所以 [left, middle - 1]
            }
        }
        return -1; // 未找到目标值
    }
};

复杂度分析

  • 时间复杂度:O(log n)
  • 空间复杂度:O(1)

二分法(左闭右开区间)

代码:

class Solution {
public:
    int search(vector<int>& nums, int target) {
        // 避免当 target 小于 nums[0] 或者 target 大于 nums[nums.size() - 1] 时多次循环运算
        if(nums[0] > target || nums[nums.size() - 1] < target) {
            return -1;
        }
 
        int left = 0;
        int right = nums.size(); // 定义 target 在左闭右开的区间里,[left, right)
 
        while(left < right) { // 当 left == right时,在区间 [left, right)是无效的,所以用 <
            int middle = left + ((right - left) >> 1); // 防止溢出 等同于(left + right)/2
            if(nums[middle] == target) { // 找到目标值,直接返回下标
                return middle;
            }else if(nums[middle] < target) {
                left = middle + 1; // target 在右区间,所以 [middle + 1, right)
            }else { // nums[middle] > target
                right = middle; // target 在左区间,所以 [left, middle)
            }
        }
        return -1; // 未找到目标值
    }
};

复杂度分析

  • 时间复杂度:O(log n)
  • 空间复杂度:O(1)

二分法(递归)(左闭右闭区间)

代码:

class Solution {
public:
    int binary(vector<int>& nums, int left, int right, int target) {
        if (nums[0] > target || nums[nums.size() - 1] < target) {
            return -1;
        }

        if (left > right) {
            return -1;
        }

        int middle = left + ((right - left) >> 1);
        if (nums[middle] == target) {
            return middle;
        } else if(nums[middle] < target) {
            return binary(nums, middle + 1, right, target);
        } else {
            return binary(nums, left, middle - 1, target);
        }
    }

    int search(vector<int>& nums, int target) {
        return binary(nums, 0, nums.size() - 1, target);
    }
};

复杂度分析

  • 时间复杂度:O(log n)
  • 空间复杂度:O(log n)

二分法(递归)(左闭右开区间)

代码:

class Solution {
public:
    int binary(vector<int>& nums, int left, int right, int target) {
        if (nums[0] > target || nums[nums.size() - 1] < target) {
            return -1;
        }
 
        if (left >= right) {
            return -1;
        }
 
        int middle = left + ((right - left) >> 1);
 
        if (nums[middle] == target) {
            return middle;
        } else if (nums[middle] < target) {
            return binary(nums, middle + 1, right, target);
        } else {
            return binary(nums, left, middle, target);
        }
    }

    int search(vector<int>& nums, int target) {
        return binary(nums, 0, nums.size(), target);
    }
  
};

复杂度分析

  • 时间复杂度:O(log n)
  • 空间复杂度:O(log n)

总结

二分查找有点类似分治思想。即每次都通过跟区间中的中间元素对比,将待查找的区间缩小为一半,直到找到要查找的元素,或者区间被缩小为 0。
二分查找的代码实现容易写错。需要注意三个容易出错的地方:

  1. 循环退出条件;
  2. middle 的取值;
  3. left 和 right 的更新。

二分查找虽然性能比较优秀,但应用场景也比较有限。底层必须依赖数组,并且还要求数据是有序的。如果数据未排序,则必须进行排序才能够使用。
对于其他的数据结构,例如链表,如果使用二分查找,每次比较都必须遍历链表寻找中间节点,时间复杂度会很高。
二分查找更适合处理静态数据,也就是没有频繁的数据插入、删除操作。而且,它更适合用在数据量较大的场景,如果数据量太小,直接顺序遍历即可。

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

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

相关文章

2024最新在线工具箱网站系统源码

(购买本专栏可免费下载栏目内所有资源不受限制,持续发布中,需要注意的是,本专栏为批量下载专用,并无法保证某款源码或者插件绝对可用,介意不要购买!购买本专栏住如有什么源码需要,可向博主私信,第二天即可发布!博主有几万资源) 2024最新在线工具箱网站系统源码是一…

怎样将excel的科学计数法设置为指数形式?

对了&#xff0c;这个问题中所谓的“指数形式”是指数学上书写的右上标的指数格式&#xff0c;能不能通过单元格设置来做这个格式的转换呢&#xff1f; 一、几个尝试 以下&#xff0c;以数字123000为例来说明。 情况1.转换成数学上的书写方式&#xff0c;如下图的样子&#x…

基于SpringBoot+Vue的二手车交易系统的设计与实现(源码+文档+包运行)

一.系统概述 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统二手车交易信息管理难度大&#xff0c;容错率低&…

Java面试八股之fail-fast和fail-safe的区别

简述fail-fast和fail-safe的区别 定义与基本概念 fail-fast&#xff1a; 定义&#xff1a;fail-fast是一种迭代器机制&#xff0c;当集合在迭代过程中被结构上修改&#xff08;如添加、删除元素&#xff09;&#xff0c;会立即抛出ConcurrentModificationException异常&…

离岸人民币与人民币国际化

参考 什么是离岸人民币&#xff1f;它有什么用&#xff1f; - 知乎 “人民币就是人民币&#xff0c;为什么要在它前面加上离岸二字&#xff1f;” “既然有离岸人民币&#xff0c;是否有在岸人民币&#xff1f;” 今天我们就简单了解一下什么是离岸人民币。 离岸/在岸人民币…

朗致集团面试-Java架构师

总结 三轮面试&#xff0c;第一轮是逻辑测试性格测试&#xff0c;第二轮是技术面试&#xff08;面试官-刘老师&#xff09;&#xff0c;第三轮是CTO面试&#xff08;面试官-屠老师&#xff09;。如果第三轮面试通过&#xff0c;考官会问你薪资意向&#xff0c;如果满意的话HR就…

5. Mysql的binlog介绍

参考&#xff1a;InnoDB学习&#xff08;三&#xff09;之BinLog 1. BinLog介绍 BinLog又称为二进制日志&#xff0c;是MySQL服务层的数据日志&#xff0c;MySQL所有的存储引擎都支持BinLog。 BinLog记录了MySQL中的数据更新和可能导致数据更新的事件&#xff0c;可以用于主从…

2024阿里云4核8G服务器租用优惠价格700元一年

阿里云4核8G服务器租用优惠价格700元1年&#xff0c;配置为ECS通用算力型u1实例&#xff08;ecs.u1-c1m2.xlarge&#xff09;4核8G配置、1M到3M带宽可选、ESSD Entry系统盘20G到40G可选&#xff0c;CPU采用Intel(R) Xeon(R) Platinum处理器&#xff0c;阿里云优惠 aliyunfuwuqi…

必应Bing国内广告推广,帮助企业降低获客成本!

搜索引擎广告作为数字营销的重要手段之一&#xff0c;因其精准定位和效果可衡量而备受青睐。而在众多搜索引擎平台中&#xff0c;必应Bing以其独特的市场定位和用户群体成为不可忽视的广告推广渠道。云衔科技作为一家专业的数字营销服务提供商&#xff0c;致力于帮助企业实现高…

代码随想录-算法训练营day15【二叉树02:层序遍历、翻转二叉树、对称二叉树】

代码随想录-035期-算法训练营【博客笔记汇总表】-CSDN博客 第六章 二叉树 part02今日内容&#xff1a; ● 层序遍历 10 ● 226.翻转二叉树 ● 101.对称二叉树 2 详细布置 层序遍历 看完本篇可以一口气刷十道题&#xff0c;试一试&#xff0c; 层序遍历并不难&#xff0c;大…

组织机构代码是哪几位?营业执照怎么看组织机构代码?

组织机构代码是哪几位? 组织机构代码通常指的是组织机构代码证上的一组特定数字&#xff0c;它用于唯一标识一个组织或机构。在中国&#xff0c;组织机构代码由9位数字组成&#xff0c;前8位是本体代码&#xff0c;最后1位是校验码。这组代码是按照国家有关标准编制的&#x…

C# danbooru Stable Diffusion 提示词反推 OpenVINO Demo

C# danbooru Stable Diffusion 提示词反推 OpenVINO Demo 目录 说明 效果 模型信息 项目 代码 下载 说明 模型下载地址&#xff1a;https://huggingface.co/deepghs/ml-danbooru-onnx 效果 模型信息 OVVersion { BuildNumber 2023.1.0-12185-9e6b00e51cd-releases/20…

kibana源码编译

一、安装nodejs16.14.2及yarn &#xff08;一&#xff09;nodejs 1、下载 https://cdn.npmmirror.com/binaries/node/v16.14.2/node-v16.14.2-linux-x64.tar.gz2、解压 tar -zxf node-v16.14.2-linux-x64.tar.gz -C /app cd /app mv node-v16.14.2-linux-x64 node3、配置环…

redmibook 14 2020 安装 ubuntu

1. 参考博客 # Ubuntu20.10系统安装 -- 小米redmibook pro14 https://zhuanlan.zhihu.com/p/616543561# ubuntu18.04 wifi 问题 https://blog.csdn.net/u012748494/article/details/105421656/# 笔记本电脑安装了Ubuntu系统设置关盖/合盖不挂起/不睡眠 https://blog.csdn.net/…

运动想象 (MI) 分类学习系列 (7) :CMO-CNN

运动想象分类学习系列:CMO-CNN 0. 引言1. 主要贡献2. 提出的算法3. 数据增强策略4. 结果4.1 学科内分类4.2 跨学科分类4.3 数据增强策略4.4 网络可视化4.4.1 短连接可视化4.4.2 滤波器可视化4.4.3 中间特征的可视化 5. 总结欢迎来稿 论文地址&#xff1a;https://www.sciencedi…

Vue3(六):Vue3其他API、Vue3新组件Teleport、Vue2和3区别

一、其他API 1.shallowRef 与 shallowReactive &#xff08;1&#xff09;shallowRef 1. 作用&#xff1a;创建一个响应式数据&#xff0c;但只对顶层属性进行响应式处理。 2.用法&#xff1a; let myVar shallowRef(initialValue); 3. 特点&#xff1a;只跟踪引用值的变化&…

C语言学习/复习22----阶段测评编程题

一、阶段测评练习 题1&#xff1a; 题2&#xff1a;

【生成式 AI 精英速成计划】了解如何使用大模型平台、训练与部署以及如何打造生成式AI应用

目录 一、生成式 AI 带来的新挑战二、生成式 AI 精英速成计划三、技术开发技能课程体验最后 一、生成式 AI 带来的新挑战 随着计算能力的飞速提升和大数据技术的广泛应用&#xff0c;生成式AI得以取得显著进展&#xff0c;特别是在深度学习的推动下&#xff0c;机器能够生成前…

Windows系统下查看C语言文件反汇编

一、配置编译器环境变量 1.下载mingw64 MinGW 的全称是&#xff1a;Minimalist GNU on Windows &#xff0c;MinGW 就是 GCC 的 Windows 版本 。 MinGW-w64 与 MinGW 的区别在于 MinGW 只能编译生成32位可执行程序&#xff0c;而 MinGW-w64 则可以编译生成 64位 或 32位 可执行…

MFC下CPictureCtrl控件基于鼠标左键坐标的直线绘图

本文仅供学习交流&#xff0c;严禁用于商业用途&#xff0c;如本文涉及侵权请及时联系本人将于及时删除 目录 1.创建自定义类CMyPictureCtrl 2.布局Dlg 3.实验代码 4.运行结果 在基于对话框的MFC应用程序中&#xff0c;通过鼠标操作获取坐标并在CPictureCtrl控件中使用Lin…