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

二分查找创新性总结

  • LeetCode题目
    • 704.二分查找
    • 35.搜索插入位置
    • 69.x 的平方根
    • 367.有效的完全平方数
    • 34.在排序数组中查找元素的第一个和最后一个位置
  • 二分查找适用范围
    • 可随机访问的数据结构
    • 数据已经有序
    • 要查找的值只有一个
  • 上述的前四题都可直接使用二分查找,第五题要求查找上限和下限,可以通过两个二分查找实现
  • 二分查找易错点
    • 容易导致重复递归
    • 边界条件不容易确定
  • 本文的创新在于:将二分查找作为一个限定范围的工具,不要求二分查找直接给出结果,而是将结果范围限制在三个值中,然后对三个值进行判断,从而无需考虑边界条件,大大降低思考难度
  • 题目讲解:以35和34为例
    • 35.搜索插入位置
    class Solution {
    private:int target;// 下列写法用于:在nums中查找最接近target的下标// 通用写法,无需考虑边界条件int bi_search(int left_index, int right_index, vector<int>& nums){// 递归中止条件if (left_index >= right_index)return right_index;auto mid_index = ((right_index - left_index) >> 1) + left_index;auto mid = nums[mid_index];// mid+1和mid-1保证不会重复递归if (mid < target)return bi_search(mid_index + 1, right_index, nums);else if (mid > target)return bi_search(left_index, mid_index - 1, nums);return mid_index;}int check(vector<int>& candidates, vector<int>& nums){auto size = nums.size();int ans = -1;for (auto& candidate : candidates) {// 必须先检查下标是否合法// 由于限制了下标必须合法,所以非法下标需要作为corner case处理if (candidate >= 0 && candidate <= (size - 1)) {// 按照顺序对ans进行更新// 若不符合条件,则不更新,因此下标的顺序很关键if (nums[candidate] >= target)ans = candidate;}}return ans;}public:int searchInsert(vector<int>& nums, int _target){target = _target;auto size = nums.size();if (0 == size)return 0;if (1 == size) {if (nums[0] >= target)return 0;else if (nums[0] < target)return 1;}// 关键步骤:保证要查找的下标一定在[0, size-1]范围内,即合法化// 因为本方法只能查找合法的下标if (nums[0] >= target)return 0;if (nums[size - 1] < target)return size;auto mid_index = bi_search(0, size - 1, nums);// 二分查找保证了最接近target的下标一定在// mid_index + 1, mid_index, mid_index - 1三个其中之一// 下标的顺序很关键:由于是查找大于等于target的下标,所以要从大到小更新vector<int> candidates { mid_index + 1, mid_index, mid_index - 1 };// 检查这三个下标,得到结果auto ans = check(candidates, nums);// 若三个小标都不符合条件,则ans=-1// 实际上已经排除了非法下标,所以无需判断// if (-1 == ans)//     return size;return ans;}
    };
    
    • 34.在排序数组中查找元素的第一个和最后一个位置
    class Solution {
    private:int target;// nums中查找target的下限的下标int bi_search_lower(int left_index, int right_index, vector<int>& nums){if (left_index >= right_index)return right_index;auto mid_index = ((right_index - left_index) >> 1) + left_index;auto mid = nums[mid_index];if (mid >= target)return bi_search_lower(left_index, mid_index - 1, nums);elsereturn bi_search_lower(mid_index + 1, right_index, nums);}// nums中查找target的上限的下标int bi_search_upper(int left_index, int right_index, vector<int>& nums){if (left_index >= right_index)return right_index;auto mid_index = ((right_index - left_index) >> 1) + left_index;auto mid = nums[mid_index];if (mid > target)return bi_search_upper(left_index, mid_index - 1, nums);elsereturn bi_search_upper(mid_index + 1, right_index, nums);}int check(vector<int>& candidates, vector<int>& nums){auto size = nums.size();int ans = -1;for (auto& candidate : candidates) {// 先判断合法性if (candidate >= 0 && candidate <= (size - 1)) {// 再更新ansif (nums[candidate] == target)ans = candidate;}}return ans;}public:vector<int> searchRange(vector<int>& nums, int _target){target = _target;auto size = nums.size();if (0 == size)return { -1, -1 };if (1 == size) {if (nums[0] == target)return { 0, 0 };return { -1, -1 };}// 保证要查找的下标是合法的if (nums[0] > target)return { -1, -1 };if (nums[size - 1] < target)return { -1, -1 };auto mid_index = bi_search_lower(0, size - 1, nums);// 找下限,要从大到小更新vector<int> candidates = { mid_index + 1, mid_index, mid_index - 1 };auto lower = check(candidates, nums);// 要处理查找失败的情况if (-1 == lower)return { -1, -1 };mid_index = bi_search_upper(0, size - 1, nums);// 找上限,要从小到大更新candidates[0] = mid_index - 1;candidates[1] = mid_index;candidates[2] = mid_index + 1;auto upper = check(candidates, nums);// 一定要处理查找失败的情况if (-1 == upper)return { -1, -1 };return { lower, upper };}
    };
    

相关文章:

二分查找创新性总结

LeetCode题目 704.二分查找35.搜索插入位置69.x 的平方根367.有效的完全平方数34.在排序数组中查找元素的第一个和最后一个位置 二分查找适用范围 可随机访问的数据结构数据已经有序要查找的值只有一个 上述的前四题都可直接使用二分查找&#xff0c;第五题要求查找上限和下限&…...

Java Web 实战 13 - 多线程进阶之 synchronized 原理以及 JUC 问题

文章目录一 . synchronized 原理1.1 synchronized 使用的锁策略1.2 synchronized 是怎样自适应的? (锁膨胀 / 升级 的过程)1.3 synchronized 其他的优化操作锁消除锁粗化1.4 常见面试题二 . JUC (java.util.concurrent)2.1 Callable 接口2.2 ReentrantLock2.3 原子类2.4 线程池…...

【解决】elementui ——tooltip提示在循环中点击一个,同时显示多个的问题!

同时显示多个tooltip——效果图&#xff1a; 点击第一个二维码把循环el-card中所有的tooltip都触发了 解决后效果图&#xff1a; 只显示点击的当前tooltip 解决办法&#xff1a; 通过循环item中定义字段&#xff0c;进行控制tooltip显示隐藏 代码&#xff1a; 页面代码&am…...

SpringBoot-核心技术篇

技术掌握导图 六个大标题↓ 配置文件web开发数据访问单元测试指标指控原理解析 配置文件 1.文件类型 1.1、properties 同以前的properties用法 1.2、yaml 1.2.1、简介 YAML是 “YAML Aint Markup Language”&#xff08;YAML不是一种标记语言&#xff09;的递归缩写。在…...

2023还有人不知道kubernetes?| 初步理解kubernetes

文章目录Kubernetes(K8s)一、Openstack&VM1、**认识虚拟化****1.1**、什么是虚拟化**1.2、虚拟化分类**2、OpenStack与KVM、VMWare2.1、OpenStack2.2、KVM2.3、VMWare二、容器&编排技术1、容器发展史1.1、Chroot1.2、FreeBSD Jails1.3、Solaris Zones1.4、LXC1.5、Dock…...

Docker 环境搭建

RabbitMq 安装与启动安装&#xff1a;运行命令&#xff1a;docker pull rabbitmq 默认版本是&#xff1a;latest启动rabbitmq&#xff1a;运行命令&#xff1a;docker run \ # 运行-e RABBITMQ_DETAULT_USERroot \ # 设置用户名-e RABBITMQ_DETAULT_PASS123456 \ # 设置 密码--…...

css实现炫酷充电动画

先绘制一个电池&#xff0c;电池头部和电池的身体 这里其实就是两个div&#xff0c;使用z-index改变层级&#xff0c;电池的身体盖住头部&#xff0c;圆角使用border-radius完成 html部分,完整的css部分在最后 <div class"chargerBox"><div class"ch…...

【Effective C++详细总结】第二章 构造/析构/赋值运算

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 &#x1f4da;专栏地址&#xff1a;C/C知识点 &#x1f4e3;专栏定位&#xff1a;整理一下 C 相关的知识点&#xff0c;供大家学习参考~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;…...

webpack基础

webpack基础 webpack基础目录webpack基础前言Webpack 是什么&#xff1f;Webpack 有什么用&#xff1f;一、webpack的基本使用webpack如何使用文件和文件夹创建创建文件下载依赖二、基本配置5 大核心概念准备 Webpack 配置文件修改配置文件处理样式资源处理图片资源修改输出资源…...

jQuery《一篇搞定》

今日内容 一、JQuery 零、 复习昨日 1 写出至少15个标签 2 写出至少7个css属性font-size,color,font-familytext-algin,background-color,background-image,background-sizewidth,heighttop,bottom ,left ,rightpositionfloatbordermarginpadding 3 写出input标签的type的不…...

Spring Cloud学习笔记【负载均衡-Ribbon】

文章目录什么是Spring Cloud RibbonLB&#xff08;负载均衡&#xff09;是什么Ribbon本地负载均衡客户端 VS Nginx服务端负载均衡区别&#xff1f;Ribbon架构工作流程Ribbon Demo搭建IRule规则Ribbon负载均衡轮询算法的原理配置自定义IRule新建MyRuleConfig配置类启动类添加Rib…...

第九章:C语言数据结构与算法初阶之堆

系列文章目录 文章目录系列文章目录前言一、堆的定义二、堆的实现三、堆的接口函数1、初始化2、销毁3、插入4、删除5、判空6、元素个数四、堆排序1、建堆2、排序五、堆的应用——TOPK1、什么是TOPK问题&#xff1f;2、解决方法总结前言 堆就是完全二叉树。 一、堆的定义 我们…...

Mysql架构初识

&#x1f972; &#x1f978; &#x1f90c; &#x1fac0; &#x1fac1; &#x1f977; &#x1f43b;‍❄️&#x1f9a4; &#x1fab6; &#x1f9ad; &#x1fab2; &#x1fab3; &#x1fab0; &#x1fab1; &#x1fab4; &#x1fad0; &#x1fad2; &#x1fad1;…...

字符串函数和内存函数

&#x1f355;博客主页&#xff1a;️自信不孤单 &#x1f36c;文章专栏&#xff1a;C语言 &#x1f35a;代码仓库&#xff1a;破浪晓梦 &#x1f36d;欢迎关注&#xff1a;欢迎大家点赞收藏关注 字符串函数和内存函数 文章目录字符串函数和内存函数前言1. 字符串函数介绍1.1 s…...

Web3中文|GPT-4超越GPT-3.5的五大看点

A Beautiful CinderellaDwelling EagerlyFinally Gains HappinessInspiring Jealous KinLove Magically Nurtures Opulent PrinceQuietly RescuesSlipper TriumphsUniting Very WondrouslyXenial Youth Zealously这是一段描述童话故事《灰姑娘》的内容&#xff0c;它出自GPT-4之…...

动态矢量瓦片缓存库方案

目录 前言 二、实现步骤 1.将数据写入postgis数据库 2.将矢量瓦片数据写入缓存库 3.瓦片接口实现 4.瓦片局部更新接口实现 总结 前言 矢量瓦片作为webgis目前最优秀的数据格式&#xff0c;其主要特点就是解决了大批量数据在前端渲染时出现加载缓慢、卡顿的问题&#xff0…...

628.三个数的最大乘积

给你一个整型数组 nums &#xff0c;在数组中找出由三个数组成的最大乘积&#xff0c;并输出这个乘积。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;6 示例 2&#xff1a; 输入&#xff1a;nums [1,2,3,4] 输出&#xff1a;24 示例 3&#xff1a; …...

【数据结构】堆和集合笔记

自己写一个堆首先&#xff0c;明确一下&#xff0c;为什么需要堆&#xff1f;>考虑插入&#xff0c;删除&#xff0c;查找的效率。数组&#xff0c;查找&#xff0c;最快是二分查找O(lgN)。但查找完如果要做什么操作&#xff0c;比如删除&#xff0c;就要挪动元素了。所以合…...

java LinkedList 源码分析(通俗易懂)

目录 一、前言 二、LinkedList类简介 三、LinkedList类的底层实现 四、LinkedList类的源码解读 1.add方法解读 : 〇准备工作 。 ①跳入无参构造。 ②跳入add方法。 ③跳入linkList方法。 ④增加第一个元素成功。 ⑤向链表中添加第二个元素。 2.remove方法解读 : 〇准备工…...

Vue中实现路由跳转的三种方式详细分解

vue中实现路由跳转的三种方式 目录 vue中实现路由跳转的三种方式 一、使用vue-router 1.下载vue-router模块到当前工程 2.在main.js中引入VueRouter函数 3.添加到Vue.use()身上 – 注册全局RouterLink和RouterView组件 4.创建路由规则数组 – 路径和组件名对应关系 5…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...

windows系统MySQL安装文档

概览&#xff1a;本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容&#xff0c;为学习者提供全面的操作指导。关键要点包括&#xff1a; 解压 &#xff1a;下载完成后解压压缩包&#xff0c;得到MySQL 8.…...

Modbus RTU与Modbus TCP详解指南

目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...

第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10+pip3.10)

第一篇&#xff1a;Liunx环境下搭建PaddlePaddle 3.0基础环境&#xff08;Liunx Centos8.5安装Python3.10pip3.10&#xff09; 一&#xff1a;前言二&#xff1a;安装编译依赖二&#xff1a;安装Python3.10三&#xff1a;安装PIP3.10四&#xff1a;安装Paddlepaddle基础框架4.1…...