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

【Go语言LeetCode刷题手记|第四天】34. 在排序数组中查找元素的第一个和最后一个位置 35. 搜索插入位置

目录

前言

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

35. 搜索插入位置 - 力扣(LeetCode)


前言

今天我们来刷两道二分查找的题目。


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

给你一个按照非递减顺序排列的整数数组nums,和一个目标值target。请你找出给定目标值在数组中的开始位置和结束位置。

如果数组中不存在目标值target,返回[-1, -1]

你必须设计并实现时间复杂度为O(log n)的算法解决此问题。

这道题目是如果用暴力做法,一个一个遍历数组找到第一个大于等于target的,并且找到最后一个小于等于target的,最坏的情况是target在数组末尾,也就是需要O(n)的时间复杂度,那我们如何才能做到O(log n)的时间复杂度呢?就需要用到我们的二分查找,设置两个指针,一个指向数组开头,一个指向数组末尾,每次取数组最中间的值mid,如果mid指向的值小于target,那么mid左边一定也小于target,反之亦然,这样我们每一次就可以得到数组中一半的元素与target的关系,也就可以将时间复杂度降低到O(log n)。具体见代码:

func searchRange(nums []int, target int) []int { start := lowerBound(nums, target) //找到第一个大于等于target的值 if start == len(nums) || nums[start] != target{ // 如果不存在,直接返回[-1,-1] return []int{-1, -1} } end := lowerBound(nums, target+1) - 1 // 找到第一个大于等于target+1的值,前一个位置就是最后一个小于等于target的位置 return []int{start, end} //返回 } func lowerBound(nums []int, target int) int { // 二分查找模板 left := 0 right := len(nums) - 1 for left <= right { mid := left + (right-left)/2 //防止溢出 if nums[mid] < target { left = mid + 1 }else { right = mid - 1 } } return left }

注意:这里的lowerBound(nums, target),相信大家都可以理解,但是如何理解lowerBound(nums, target+1) - 1这行代码?这就需要用到一个小技巧,这样我们用下面这套模板就可以解决四种情况的问题(第一个>target,第一个>=target,最后一个<target,最后一个<=target)。

func lowerBound(nums []int, target int) int { left := 0 right := len(nums) - 1 for left <= right { mid := left + (right-left)/2 if nums[mid] < target { left = mid + 1 }else { right = mid - 1 } } return left }

第一个>=target的值我们可以直接用lowerBound(nums, target),第一个>target的值我们可以转化为第一个>=target+1,最后一个<=target可以转化为第一个>target的值的前一个位置,最后一个<target可以转化为第一个>=target的值的前一个位置,如下表:

第一个≥ target直接lowerBound(target)lowerBound(nums, target)
第一个> target第一个≥ (target+1)lowerBound(nums, target+1)
最后一个≤ target第一个> target前一个位置lowerBound(nums, target+1) - 1
最后一个< target第一个≥ target前一个位置lowerBound(nums, target) - 1

这样我们只用一套模板就可以解决全部二分查找的问题。

35. 搜索插入位置 - 力扣(LeetCode)

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

请必须使用时间复杂度为O(log n)的算法。

这道题目也是有一个标准的二分查找模板题,相信搞懂了上一题,这道题目也不在话下,直接秒杀,代码:

func searchInsert(nums []int, target int) int { return lowerBound(nums, target) } func lowerBound(nums []int, target int) int { left := 0 right := len(nums) - 1 for left <= right { mid := left + (right-left)/2 if nums[mid] < target { left = mid + 1 }else { right = mid - 1 } } return left }
http://www.rkmt.cn/news/1484724.html

相关文章:

  • 2026年最新呼伦贝尔市黄金+白银+铂金+K金回收门店及联系方式电话推荐 黄金回收店铺TOP5排行榜 - 盛世金银回收
  • 2026年最新防城港市黄金+白银+铂金+K金回收门店及联系方式电话推荐 黄金回收店铺TOP5排行榜 - 盛世金银回收
  • Kaggle房价预测翻车实录:从梯度爆炸到模型保存,我的PyTorch MLP调参避坑指南
  • 别再手动敲OWL了!用Protege+Cellfie批量处理Excel数据,完整配置流程与字符清洗脚本
  • 计算机原理与硬件基础入门指南——写给零基础在职人员的通俗教程
  • S32K3系列CAN接收过滤避坑指南:从MB0全收不到精准掩码设置,手把手教你搞定报文丢失问题
  • 2026年最新佛山市黄金+白银+铂金+K金回收门店及联系方式电话推荐 黄金回收店铺TOP5排行榜 - 盛世金银回收
  • 2026年最新昆明市黄金回收店铺TOP5排行榜 黄金+白银+铂金+K金回收门店指南及联系方式电话推荐 - 大熊猫898989
  • 2026年淄博采购供应商岗位SCMP试听课怎么问?众智商学院官网费用班期 - 众智商学院职业教育
  • 从‘一视同仁’到‘区别对待’:图解Circle Loss如何给难样本‘加权重’,PyTorch代码逐行解析
  • 2026年最新福州市黄金+白银+铂金+K金回收门店及联系方式电话推荐 黄金回收店铺TOP5排行榜 - 盛世金银回收
  • 2026年最新兰州市黄金回收店铺TOP5排行榜 黄金+白银+铂金+K金回收门店指南及联系方式电话推荐 - 大熊猫898989
  • 罗马尼亚语模型训练:Transformer与Mamba架构对比与优化
  • 2026年最新蚌埠市黄金回收店铺TOP5排行榜 黄金+白银+铂金+K金回收门店指南及联系方式电话推荐 - 大熊猫898989
  • 告别调度表依赖:用RTA-OS Alarm实现精准定时任务(附SetAbsAlarm/SetRelAlarm代码示例)
  • 告别裸机,在FreeRTOS上为STM32移植SOEM EtherCAT主站的几点关键考量
  • 跨越二层交换机:华为交换机802.1X认证中EAP报文透传的完整配置流程与原理
  • 从Jupyter到生产环境:机器学习模型服务化落地实战
  • POE仿生硬件设计法:原理-组织-执行三层落地模型
  • 2026年最新大同市黄金+白银+铂金+K金回收门店及联系方式电话推荐 黄金回收店铺TOP5排行榜 - 盛世金银回收
  • MuleSoft企业级AI编排:安全可控的LLM集成实践
  • 从PCB布线到天线设计:工程师必懂的传输线‘黑话’与实战避坑指南
  • 2026年最新宝鸡市黄金回收店铺TOP5排行榜 黄金+白银+铂金+K金回收门店指南及联系方式电话推荐 - 大熊猫898989
  • 别再到处找外围电路了!用ESP32-PICO-D4做超小型物联网设备,一个芯片就够了
  • 5G手机信号到底有多强?手把手教你读懂3GPP 38.521-1中的SUL功率配置与测试
  • 在Hi3516DV300开发板上手把手搭建WiFi热点:hostapd 2.9交叉编译与RT3070网卡配置全流程
  • 2026年最新保山市黄金回收店铺TOP5排行榜 黄金+白银+铂金+K金回收门店指南及联系方式电话推荐 - 大熊猫898989
  • 2026年最新广安市黄金+白银+铂金+K金回收门店及联系方式电话推荐 黄金回收店铺TOP5排行榜 - 盛世金银回收
  • KingbaseES存储空间告警?先学会这招快速定位‘空间大户’表和数据库
  • 别再手动记测点了!UaExpert 1.5.1拖拽式连接OPC UA服务器,5分钟搞定数据监控