二分查找创新性总结
- 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.在排序数组中查找元素的第一个和最后一个位置 二分查找适用范围 可随机访问的数据结构数据已经有序要查找的值只有一个 上述的前四题都可直接使用二分查找,第五题要求查找上限和下限&…...

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——效果图: 点击第一个二维码把循环el-card中所有的tooltip都触发了 解决后效果图: 只显示点击的当前tooltip 解决办法: 通过循环item中定义字段,进行控制tooltip显示隐藏 代码: 页面代码&am…...

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

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 安装与启动安装:运行命令:docker pull rabbitmq 默认版本是:latest启动rabbitmq:运行命令:docker run \ # 运行-e RABBITMQ_DETAULT_USERroot \ # 设置用户名-e RABBITMQ_DETAULT_PASS123456 \ # 设置 密码--…...

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

【Effective C++详细总结】第二章 构造/析构/赋值运算
✍个人博客:https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 📚专栏地址:C/C知识点 📣专栏定位:整理一下 C 相关的知识点,供大家学习参考~ ❤️如果有收获的话,欢迎点赞👍…...
webpack基础
webpack基础 webpack基础目录webpack基础前言Webpack 是什么?Webpack 有什么用?一、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(负载均衡)是什么Ribbon本地负载均衡客户端 VS Nginx服务端负载均衡区别?Ribbon架构工作流程Ribbon Demo搭建IRule规则Ribbon负载均衡轮询算法的原理配置自定义IRule新建MyRuleConfig配置类启动类添加Rib…...

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

Mysql架构初识
🥲 🥸 🤌 🫀 🫁 🥷 🐻❄️🦤 🪶 🦭 🪲 🪳 🪰 🪱 🪴 🫐 🫒 🫑…...

字符串函数和内存函数
🍕博客主页:️自信不孤单 🍬文章专栏:C语言 🍚代码仓库:破浪晓梦 🍭欢迎关注:欢迎大家点赞收藏关注 字符串函数和内存函数 文章目录字符串函数和内存函数前言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这是一段描述童话故事《灰姑娘》的内容,它出自GPT-4之…...

动态矢量瓦片缓存库方案
目录 前言 二、实现步骤 1.将数据写入postgis数据库 2.将矢量瓦片数据写入缓存库 3.瓦片接口实现 4.瓦片局部更新接口实现 总结 前言 矢量瓦片作为webgis目前最优秀的数据格式,其主要特点就是解决了大批量数据在前端渲染时出现加载缓慢、卡顿的问题࿰…...
628.三个数的最大乘积
给你一个整型数组 nums ,在数组中找出由三个数组成的最大乘积,并输出这个乘积。 示例 1: 输入:nums [1,2,3] 输出:6 示例 2: 输入:nums [1,2,3,4] 输出:24 示例 3: …...
【数据结构】堆和集合笔记
自己写一个堆首先,明确一下,为什么需要堆?>考虑插入,删除,查找的效率。数组,查找,最快是二分查找O(lgN)。但查找完如果要做什么操作,比如删除,就要挪动元素了。所以合…...

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…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...