[Algorithm][二分查找][在排序数组中查找元素的第一个和最后一个位置][x 的平方根]详细讲解

目录

  • 1.在排序数组中查找元素的第一个和最后一个位置
    • 1.题目链接
    • 2.算法原理详解
      • 1.查找区间左端点
      • 2.查找区间右端点
    • 3.代码实现
  • 2.x 的平方根
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现


1.在排序数组中查找元素的第一个和最后一个位置

1.题目链接

  • 在排序数组中查找元素的第一个和最后一个位置

2.算法原理详解

1.查找区间左端点

  • 令中间值为x,目标值为t
  • 如何迭代?
    • x < t -> left = mid + 1 -> [left, right]
    • x >= t -> right = mid -> [left, right]
  • 细节处理:
    • 循环条件left < right
    • 求中点方式left + (right - left) / 2 -> 向下取整
  • 循环条件为什么不能包含left == right
    • left == right的时候,就是最终结果,无需判断
    • 如果判断,就会陷入死循环
      • 如果最后一次判断条件为x < t -> left = mid + 1 -> [left, right]
        • 则没问题,正常结束
      • 如果最后一次判断条件为x >= t -> right = mid -> [left, right]
        • 则会一直right = mid,陷入死循环
  • 求中点方式为什么是left + (right - left) / 2
    • 偶数时:求的是左端点
    • 如果最后一次判断条件为x < t -> left = mid + 1 -> [left, right]
      • 则没问题,正常结束
    • 如果最后一次判断条件为x >= t -> right = mid -> [left, right]
      • 则会一直right = mid,陷入死循环
        ![[Pasted image 20240327221405.png]]

2.查找区间右端点

  • 令中间值为x,目标值为t
  • 如何迭代?
    • x <= t -> left = mid -> [left, right]
    • x > t -> right = mid - 1 -> [left, right]
  • 细节处理:
    • 循环条件left < right
    • 求中点方式left + (right - left + 1) / 2 -> 向上取整
  • 循环条件为什么不能包含left == right
    • left == right的时候,就是最终结果,无需判断
    • 如果判断,就会陷入死循环
      • 如果最后一次判断条件为x > t -> right = mid - 1 -> [left, right]
        • 则没问题,正常结束
      • 如果最后一次判断条件为x <= t -> left = mid -> [left, right]
        • 则会一直left = mid,陷入死循环
  • 求中点方式为什么是left + (right - left + 1) / 2
    • 偶数时:求的是右端点
    • 如果最后一次判断条件为x > t -> right = mid - 1 -> [left, right]
      • 则没问题,正常结束
    • 如果最后一次判断条件为x <= t -> left = mid -> [left, right]
      • 则会一直left = mid,陷入死循环
        请添加图片描述

3.代码实现

vector<int> searchRange(vector<int>& nums, int target) 
{// 处理边界情况if(nums.size() == 0){return {-1, -1};}// 二分左端点int left = 0, right = nums.size() - 1;while(left < right){int mid = left + (right - left) / 2;if(nums[mid] < target){left = mid + 1;}else{right = mid;}}int begin = 0;if(nums[left] == target){begin = left; // 标记左端点}else{return {-1, -1};}// 二分右端点// 这里其实left可以不做处理,算一个小优化left = 0, right = nums.size() - 1;while(left < right){int mid = left + (right - left + 1) / 2;if(nums[mid] <= target){left = mid;}else{right = mid - 1;;}}return {begin, right};
}

2.x 的平方根

1.题目链接

  • x 的平方根

2.算法原理详解

  • 本题虽然可以直接遍历求值,但是时间复杂度为O(N),显然效率不高
  • 可以把问题抽象成,在数组 [ 1 , x ] [1, x] [1,x]内,找x的平方根
    • 此时,数组具有二段性,可以用二分查找
      请添加图片描述

3.代码实现

int MySqrt(int x) 
{// 处理边界情况if(x < 1){return 0;}int left = 1, right = x;while(left < right){long long mid = left + (right - left + 1) / 2;if(mid * mid <= x){left = mid;}else{right = mid - 1;}}return left;
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Rust序列化和反序列化

Rust 编写python 模块 必备库 docker 启动 nginx 服务 NGINX 反向代理配置

Spring Boot | Spring Boot 默认 “缓存管理“ 、Spring Boot “缓存注解“ 介绍

目录: 一、Spring Boot 默认 "缓存" 管理 :1.1 基础环境搭建① 准备数据② 创建项目③ 编写 "数据库表" 对应的 "实体类"④ 编写 "操作数据库" 的 Repository接口文件⑤ 编写 "业务操作列" Service文件⑥ 编写 "applic…

01-服务与服务间的通信

这里是极简版&#xff0c;仅用作记录 概述 前端和后端可以使用axios等进行http请求 服务和服务之间也是可以进行http请求的spring封装的RestTemplate可以进行请求 用法 使用bean注解进行依赖注入 在需要的地方&#xff0c;自动注入RestTemplate进行服务和服务之间的通信 注…

rancher-rke2 修改--service-cluster-ip-range

一、场景 因为需要部署新版本的ingress-nginx&#xff0c;而部署ingress-nginx的时候需要使用hostnetowrk以及nodeport的端口为80和443&#xff0c;service-node-port-range 默认为30000开始,部署会报错。 二、产生修改的需求 1、api-servier的配置文件位置 默认是没有的&…

Chrome 侧边栏开发示例

前言 最近做项目&#xff0c;需要开发浏览器扩展&#xff0c;但是考虑页面布局兼容性问题&#xff0c;使用了Chrome114开始的侧边栏&#xff0c;浏览器自带的能力毕竟不会出现兼容性问题&#xff0c;不过Chrome123开始&#xff0c;侧边栏居然又可以选择固定右侧扩展栏了&#…

C语言进阶课程学习记录-函数参数的秘密

C语言进阶课程学习记录-函数参数的秘密 实验实验小结调用约定实验-求平均数实验-可变参数的函数小结 本文学习自狄泰软件学院 唐佐林老师的 C语言进阶课程&#xff0c;图片全部来源于课程PPT&#xff0c;仅用于个人学习记录 实验 #include <stdio.h>int func(int i, int…

第15届蓝桥杯题解

A题 结果&#xff1a;2429042904288 思路很简单 前20个数分别是 20 24 40 48 60 72 80 96 100 120 140 144 160 168 180 192 200 216 220 240 第2 4 6 8 12 ...n个数分别是24的 1倍 2倍 3倍 4倍 6倍 n/2倍 所以第202420242024 个数就是 24的 101210121012倍 B题 答案&am…

嵌入式Linux开发实操(十八):Linux音频ALSA开发

应用程序程序员应该使用库API,而不是内核API。alsa库提供了内核API 100%的功能,但增加了可用性方面的主要改进,使应用程序代码更简单、更美观。未来的修复程序或兼容性代码可能会放在库代码中,而不是放在内核驱动程序中。 使用ALSA API和libasound进行简单的声音播放: /*…

生态短讯 | Tapdata 与 TDengine 完成产品兼容性互认证,打造物联网实时数据生态

近月&#xff0c;深圳钛铂数据有限公司&#xff08;以下简称钛铂数据&#xff09;自主研发的实时数据平台&#xff08;Tapdata Live Data Platform&#xff09;与北京涛思数据科技有限公司&#xff08;以下简称涛思数据&#xff09;自主研发的大数据平台 TDengine&#xff0c;已…

八、每晚准时入眠的五个关键要素(The 5 Keys to Falling Asleep On Time Every Night)

The best book I’ve read on sleep is Matthew Walker’s Why We Sleep. In it, he explains the importance of getting good sleep as well as offers suggestions for how to avoid problems of nighttime insomnia. 关于睡眠问题&#xff0c;我读过的最好的书是马修沃克(M…

【未完成】【QT+OpenCV】车牌号检测 学习记录 遇到的问题

【QTOpenCV】车牌号检测 学习记录 首先在QT里面配置好OpenCV .pro文件中加入&#xff1a; INCLUDEPATH G:/opencv/build/include LIBS -L"G:/opencv/build/x64/vc14/lib"\-lopencv_core \-lopencv_imgproc \-lopencv_highgui \-lopencv_ml \-lopencv_video \-lo.c…

FPGA片内RAM读写代码示例

RAM(Random Access Memory)&#xff0c;也就是随机存取寄存器&#xff0c;它可以随时把数据数据写入任一指定地址的存储单元&#xff0c;也可以随时从任一指定地址中读出数据&#xff0c;其读写速度是由时钟频率决定的。 在本例程汇总&#xff0c;实现了向RAM里面写入1024个数据…