当前位置: 首页 > 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.jsqmd.com/news/973001/

相关文章:

  • llms.txt配置详解:让AI更好地理解你的网站
  • 2026年最新日照市黄金回收店铺TOP5排行榜 黄金+白银+铂金+K金回收门店指南及联系方式电话推荐 - 大熊猫898989
  • 2026年最新酒泉市黄金回收店铺TOP5排行榜 黄金+白银+铂金+K金回收门店指南及联系方式电话推荐 - 大熊猫898989
  • 保姆级教程:汇川InoProShop软件中5种全局变量的区别与实战配置(含掉电保持)
  • 华为路由器DHCP配置实操:终端动态获取IP
  • Kaggle房价预测翻车实录:从梯度爆炸到模型保存,我的PyTorch MLP调参避坑指南
  • 2026年最新防城港市黄金+白银+铂金+K金回收门店及联系方式电话推荐 黄金回收店铺TOP5排行榜 - 盛世金银回收
  • 芝加哥/纽约/华盛顿共享单车数据本地分析脚本(Python命令行版)
  • JSON高频踩坑指南:避坑技巧与实战代码
  • 计算机原理与硬件基础入门指南——写给零基础在职人员的通俗教程
  • 别再手动敲OWL了!用Protege+Cellfie批量处理Excel数据,完整配置流程与字符清洗脚本
  • 2026年最新三门峡市黄金回收店铺TOP5排行榜 黄金+白银+铂金+K金回收门店指南及联系方式电话推荐 - 大熊猫898989
  • 2026年最新开封市黄金回收店铺TOP5排行榜 黄金+白银+铂金+K金回收门店指南及联系方式电话推荐 - 大熊猫898989
  • 告别‘元芳你怎么看’:用pyltp的SentenceSplitter和Segmentor搞定中文文本预处理(附完整代码)
  • 2026年最新湖州市黄金+白银+铂金+K金回收门店及联系方式电话推荐 黄金回收店铺TOP5排行榜 - 盛世金银回收
  • 2026年最新佛山市黄金+白银+铂金+K金回收门店及联系方式电话推荐 黄金回收店铺TOP5排行榜 - 盛世金银回收
  • S32K3系列CAN接收过滤避坑指南:从MB0全收不到精准掩码设置,手把手教你搞定报文丢失问题
  • 微生物组学入门:手把手教你选择和使用Greengenes、SILVA、RDP三大16S数据库
  • 机器学习新手必备:掌握这六大预测模型,开启数据科学之旅
  • x64汇编案例5
  • 用51单片机和ADC0809做个简易电压表,从Proteus仿真到实物焊接全流程(附源码)
  • 2026年最新白山市黄金回收店铺TOP5排行榜 黄金+白银+铂金+K金回收门店指南及联系方式电话推荐 - 大熊猫898989
  • 2026年最新昆明市黄金回收店铺TOP5排行榜 黄金+白银+铂金+K金回收门店指南及联系方式电话推荐 - 大熊猫898989
  • LOFAR与uGMRT联合观测星系团射电晕的技术解析
  • 2026年最新三明市黄金回收店铺TOP5排行榜 黄金+白银+铂金+K金回收门店指南及联系方式电话推荐 - 大熊猫898989
  • 2026年最新怀化市黄金+白银+铂金+K金回收门店及联系方式电话推荐 黄金回收店铺TOP5排行榜 - 盛世金银回收
  • 从‘一视同仁’到‘区别对待’:图解Circle Loss如何给难样本‘加权重’,PyTorch代码逐行解析
  • 2026年淄博采购供应商岗位SCMP试听课怎么问?众智商学院官网费用班期 - 众智商学院职业教育
  • 告别‘我’字打不出!手把手教你为手心输入法配置完整的自然码辅码表(附下载)
  • 罗马尼亚语NLP模型优化与低资源语言处理实践