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

二分算法(模板)

例题1:

704. 二分查找 - 力扣(LeetCode)

算法原理:(二分)

通过遍历也可以通过,但是二分更优且数据量越大越能体现。

二分思路:

1.mid1 =  (left + right)/2 与 mid2 = right + (right - left)/2区别。

如果不考虑数据范围: (left + right)/2  = right + (right - left)/2,但越界就不一样了。

mid1 =  (left + right)/2 :可能越界

mid2 = left+ (right - left)/2 : 可以防止越界

2.mid1 = (right + left)/2 与 mid2 = (right + left + 1)/2区别。

(right + left)/2  : 向下取整

(right + left + 1)/2 :向上取整

举个例子: right = 3,left = 4,(right + left)/2  = 3,(right + left + 1)/2 = 4;

                   right = 2,left = 4,(right + left)/2  = 3,(right + left + 1)/2 = 3;

这里不会严格用数学方式去证明,那样太花时间了,感兴趣的话网上搜搜,我们直接给出结论,当right + left 结果为偶数时,mid1 与 mid2 是没有区别的,但结果为奇数时就会相差1,不要小看了这一点区别,不注意这里,就很有可能写出死循环,具体我们在下面例题里体现。

这里不能通过调整上下取整的方式来避免死循环。但是可以通过增加一行代码来弄

(       if(left == right && nums[left] != target) break;      )

代码:

//暴力可以过😯public int search(int[] nums, int target) {int n = nums.length;for(int i = 0;i < n;i++){if(nums[i] > target){break;}if(nums[i] == target) return i;}return -1;}
     //二分public int search(int[] nums, int target) {int left = 0;int right = nums.length - 1;while(left <= right){int mid = left + (right - left)/2;if(nums[mid] < target){left = mid+1;}else if(nums[mid] ==target){return mid;}else {right = mid-1;}}return -1;}
//二分,调整后public int search(int[] nums, int target) {int left = 0;int right = nums.length - 1;while(left <= right){int mid = left + (right - left)/2;if(nums[mid] < target){left = mid+1;}else if(nums[mid] ==target){return mid;}else {right = mid;}if(left == right && nums[left] != target) break; }return -1;}

 

通过上面两幅幅图我们就可以感受到上,下取整差1,如果调整不好便会出现死循环。这里只列举了向下取整,避免死循环情况。还有一种是向上取整,避免死循环情况。(再往下的例题就不会,所这么多了。) 

如下例题都是可以利用二分解决的,这里就提一点,二分的使用场景并不一定非要整个序列有序,而是依据你的需求,巧妙的去使用它。

例题2:

34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣(LeetCode)

例题3:

162. 寻找峰值 - 力扣(LeetCode)

例题4:

153. 寻找旋转排序数组中的最小值 - 力扣(LeetCode)

http://www.xdnf.cn/news/17846.html

相关文章:

  • week1-[顺序结构]大海
  • 9.对象介绍
  • 俄罗斯信封套娃问题-二维最长递增子序列
  • BFS和codetop复习
  • 【Java Web 快速入门】十、AOP
  • 自动处理考勤表——如何使用Power Query,步步为营,一点点探索自定义函数
  • LeetCode Hot100:递归穿透值传递问题
  • 艾伦·图灵:计算理论与人工智能的奠基人
  • Java研学-SpringCloud(四)
  • Numerical Difference between vLLM logprobs and huggingface logprobs
  • 数据结构:N叉树 (N-ary Tree)
  • Web 开发 15
  • 4.2 寻址方式 (答案见原书 P341)
  • CIAIE 2025上海汽车内外饰展观察:从美学到功能的产业跃迁
  • Tokenizer(切词器)的不同实现算法
  • 《软件工程导论》实验报告四 详细设计工具
  • 打靶日常-sql注入(手工+sqlmap)
  • 嵌入式学习 day52 IMX6ULL裸机开发-I2C
  • 功能组和功能组状态的概念关系和区别
  • Cursor/VSCode/VS2017 搭建Cocos2d-x环境,并进行正常的调试和运行(简单明了)
  • Docker的相关知识探究详解
  • Linux驱动学习day28(USB驱动,libusb操作)
  • RabbitMQ核心架构与应用
  • DeepSeek-V2:一种强大、经济且高效的混合专家语言模型
  • 区块链技术原理(13)-以太坊燃料费Gas
  • 【数据结构初阶】--排序(三):冒泡排序、快速排序
  • 旋钮键盘项目---foc讲解(开环)
  • 基于WSL搭建Ubuntu 22.04.x LTS开发环境
  • 102、【OS】【Nuttx】【周边】文档构建渲染:安装 Esbonio 服务器
  • Codeforces 无路可走