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

【二分算法】模板总结

目录

一、二分查找时间复杂度

二、二分查找模板

2.1 模板一:标准的二分查找

2.2 模板二:二分查找左边界

2.3 模板三:二分查找右边界

三、总结:


一、二分查找时间复杂度

时间复杂度可以表示 O(n)=O(log2​n)或者O(n)=O(logn)

二、二分查找模板

什么时候可能需要用二分查找?

(1)待查找的数组有序或者部分有序

(2)可以发现二段性

(3)题目要求时间复杂度低于 O(n),或者直接要求时间复杂度为 O(log n)

2.1 模板一:标准的二分查找

适用场景:数组元素有序且不重复

public int search(int[] nums, int target) {int left = 0,right = nums.length-1;while(left<=right) {int mid = left + ((right-left)>>1);//+运算的优先级高if(target==nums[mid]) return mid;else if(nums[mid]<target) left = mid+1;else right = mid-1;}return -1;}

注意点:

(1)为什么 while 循环的条件是 <=,而不是 < ?

当元素只有一个且这个元素正好就是目标值,那么没有=就进入不了循环,得不到正确的结果

(2)计算 mid 时需要防止溢出

left + ((right -left) >> 1) 其实和 (left + right) / 2 是等价的,这样写的目的一个是为了防止 (left + right) 出现溢出,另外用位运算替代除法提升性能


2.2 模板二:二分查找左边界

public int search(int[] nums, int target) {int left =0,right = nums.length-1;while(left<right) {//1.int mid = left+(right-left)/2;//2.if(nums[mid]<target) left = mid+1;//3.else right = mid;}if(nums[left]==target) return left;return -1;}

注意点:

(1)为什么 while 循环的条件是 <,而不是 <= ?

left等于right的时候就已经得到了最终结果,如果判断了,就会进入死循环,因为right后面一直不动

(2) 求中点的操作

求左边界根标准模板一样,不用+1,直接left+(right-left)/2(总个数为偶数个时取中点的时候取左边那个

(3)为啥nums[mid]==target右边界也要变

要寻找左边界,当nums[mid] == target,这个mid的位置不一定就是最左侧的那个边界,所以还要继续收缩右边界

2.3 模板三:二分查找右边界

public int search(int[] nums, int target) {int left =0,right = nums.length-1;while(left<right) {//1.int mid = left+(right-left+1)/2;//2.if(nums[mid]>target) right = mid-1;//3.else left=mid;}if(nums[right]==target) return right;return -1;}

注意点:

(1)为什么 while 循环的条件是 <,而不是 <= ?

left等于right的时候就已经得到了最终结果,如果判断了,就会进入死循环,因为right后面一直不动

(2) 求中点的操作

这个和求左边界不一样,需要+1,即left+(right-left+1)/2(总个数为偶数个时取中点的时候取右边那个),因为如果最后剩两个元素的时候,left一直找左边那个元素,那么将会进入死循环

(3)为啥nums[mid]==target左边界也要变

要寻找右边界,当nums[mid] == target,这个mid的位置不一定就是最右侧的那个边界,所以还要继续收缩左边界


三、总结:

(1)左+1,右不变

找左边界时,left = mid+1;找右边界,left = mid

(2)下面出现-1的时候,上面就要+1

 mid-1出现,那么上面求mid就需要+1


http://www.mrgr.cn/news/34223.html

相关文章:

  • Matplotlib库中show()函数的用法
  • Hadoop学习--第一章 Hello大数据分布式
  • PostgreSQL 开启密码验证插件
  • 【api】java和python联动
  • 对node工程进行压力测试与性能分析
  • AI生活之我用AI处理Excel表格
  • 系统分析师12:系统规划
  • 沁恒CH32V307读写flash出错
  • 远程升级频频失败?你可能忽略了模组差分包…
  • 学生宿舍管理:Spring Boot框架的高效策略
  • Apache Iceberg 概述
  • HOJ网站开启https访问 申请免费SSL证书 部署证书详细操作指南
  • 现代前端框架实战指南:React、Vue.js、Angular核心概念与应用
  • 【数列求值 / B】
  • 手把手教您轻松实现微信/QQ/TIM多开,消息防撤回!
  • 机械手末端快换技术:工业自动化的强大新动力
  • python:django项目知识点02——搭建简易授权码核销系统
  • 记录我的常用开发地址
  • 骨传导耳机推荐什么牌子好?盘点五款高性价比热门机型推荐!
  • Azure Pipeline 常用任务记录
  • Kubernetes之Kubectl命令行工具操作
  • 【C++】哈希桶
  • 第十一章 从0-1搭建一个简单的JavaWeb系统(三)
  • Python 列表操作:深入理解与高效实践
  • Science:这才是参加学术会议的正确打开方式!
  • 20 基于STM32的温度、电流、电压检测proteus仿真系统(OLED、DHT11、继电器、电机)