当前位置:网站首页>LeetCode50天刷题计划(Day 19—— 在排序数组中查找元素的第一个和最后一个位置(9.10-10.40)
LeetCode50天刷题计划(Day 19—— 在排序数组中查找元素的第一个和最后一个位置(9.10-10.40)
2022-08-10 11:01:00 【国际知名观众】
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
啊 好困 啊
一、题目
在排序数组中查找元素的第一个和最后一个位置
给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。
示例
示例 1:
输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]
示例 2:
输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]
示例 3:
输入:nums = [], target = 0
输出:[-1,-1]
提示
0 <= nums.length <= 105
-109 <= nums[i] <= 109
nums 是一个非递减数组
-109 <= target <= 109
二、思路
由于时间复杂度的要求,考虑先二分搜索出一个解(O(logn)),然后向其前后扩散线性查找全部解。
但第二步可能会导致时间超限,故考虑用两次细节条件不同的二分查找依次找出前边界和后边界。
根据情况,每次选择可能出现目标值的一部分元素,就是二分查找的核心思想。比如:
【第一次】查找首次出现的target时(left=0,right=n-1,首边界re1)
mid=[(left+right)/2]向下取整
如果midtarget,那么首边界应在[left,mid](闭区间)中
如果mid<target,那么首边界应在[mid+1,right](闭区间)中
如果mid>target,那么首边界应在[left,mid-1](闭区间)中
使左右指针不断聚拢,直至相遇,如果相遇时该元素恰好值为target,则寻找成功,否则说明数组中没有此元素,查找失败
【第二次】mid=[(left+right)/2]向上取整【为了满足left、mid、right三者相同都是target的情况】
如果首次可以查找到target首边界,才需要进行第二次查找尾边界,否则直接返回即可(left=re1,right=n-1,尾边界re2)
如果midtarget,那么尾边界应在[mid,right](闭区间)中
如果mid<target,那么尾边界应在[mid+1,right](闭区间)中
如果mid>target,那么首边界应在[left,mid-1](闭区间)中
找到左右指针相遇的地方,就是尾边界
三、代码
1.二分+线性(python)
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
#很明显,还是用二分搜索 先找到一个然后向前后扩散!
n=len(nums)-1
center=-1
#二分搜索
left=0
right=n
while(left<=right):
mid=(left+right)//2
#print(left,right,mid)
if(nums[mid]==target):
center=mid
break
elif(nums[mid]>target):
right=mid-1
else:
left=mid+1
#向两边扩散
if(center==-1):
return [-1,-1]
else:
left=right=center
while(left>=1 and nums[left-1]==nums[center]):
left-=1
while(right+1<=n and nums[right+1]== nums[center]):
right+=1
return[left,right]

2.二分+二分
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
n=len(nums)-1 #尾下标值
if(n<0): #空列表
return [-1,-1]
re1=-1 #左边界
#第一次二分搜索
left=0
right=n
while(left<right):
mid=(left+right)//2 #向下取整
if(nums[mid]==target):
right=mid
elif(nums[mid]>target):
right=mid-1
else:
left=mid+1
#出循环时一定有left==right
if(nums[left]==target): #找到
re1=left
else: #没找到
return [-1,-1]
#第二次二分搜索
left=re1
right=n
while(left<right):
mid=(left+right+1)//2 #向上取整
if(nums[mid]==target):
left=mid
elif(nums[mid]>target):
right=mid-1
else:
left=mid+1
#一定能找到尾,直接返回
return [re1,left]

边栏推荐
- 3 injured in 'electrical accident' at Google data center
- Double.doubleToLongBits()方法使用
- 【TypeScript】接口类型与类型别名:这两者的用法与区别分别是什么?
- POJ 3101 Astronomy (数学)
- 蔚来-软件开发工程师一面记录
- 自媒体爆款标题怎么写?手把手教你写热门标题
- mysql出现:ERROR 1524 (HY000): Plugin ‘123‘ is not loaded
- 力扣练习——56 寻找右区间
- Get started quickly and conquer three different distributed architecture calling schemes
- Double.doubleToLongBits() method uses
猜你喜欢

从脚本到剪辑,影像大师亲授的后期制作秘籍

3 injured in 'electrical accident' at Google data center

为什么Redis很快

微信小程序,全局变量一个地方改变了其他地方的状态也跟着改变。

基于UiAutomator2+PageObject模式开展APP自动化测试实战

AUTOCAD——减少样条曲线控制点数、CAD进阶练习(三)

什么是抽象类

STM32 encapsulation ESP8266 a key configuration function: implementations of AP mode and the STA mode switch, server and the client to create

Pycharm终端出现PS问题、conda或activate不是内部命令问题..
![[Go WebSocket] 多房间的聊天室(一)思考篇](/img/c9/4374a57c6a4ae02f606253a4c299e4.png)
[Go WebSocket] 多房间的聊天室(一)思考篇
随机推荐
电脑怎么设置屏幕息屏时间(日常使用分享)
Do self-media monthly income tens of thousands?Several self-media tools that bloggers are using
力扣练习——58 验证二叉搜索树
2022年裁员潮,失业程序员何去何从?
LeetCode_443_压缩字符串
4 of huawei offer levels, incredibly side is easing the bit in the interview ali?
老板加薪!看我做的WPF Loading!!!
十年架构五年生活-09 五年之约如期而至
runtime-core.esm-bundler.js?d2dd:218 Uncaught TypeError: formRef.value?.validate is not a function
软件架构简介
从产品维度来看 我们为什么不能完全信任Layer2?
From the product dimension, why can't we fully trust Layer2?
Unsafe的一些使用技巧
Memory problems difficult to locate, it is because you do not use ASAN
Redis设计与实现
How can an organization judge the success of data governance?
越折腾越好用的 3 款开源 APP
基于UiAutomator2+PageObject模式开展APP自动化测试实战
Alibaba最新神作!耗时182天肝出来1015页分布式全栈手册太香了
Break through the dimensional barriers and let the dolls around you move on the screen!