当前位置:网站首页>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]

边栏推荐
- runtime-core.esm-bundler.js?d2dd:218 Uncaught TypeError: formRef.value?.validate is not a function
- Intel pushes 20220809 CPU microcode update to patch Intel-SA-00657 security vulnerability
- 从脚本到剪辑,影像大师亲授的后期制作秘籍
- SQL与NoSQL最终会走向融合吗?
- OSSCore 开源解决方案介绍
- Article take you understand interrupt the key driver of polling mechanism
- 【勇敢饭饭,不怕刷题之链表】链表倒数节点问题
- A little self-deprecating deconstruction about farmers "code"
- ISO9001在讲什么?过程方法和风险思维
- 是什么影响了MySQL性能?
猜你喜欢
随机推荐
The brave rice rice, does not fear the brush list of 】 list has a ring
微信小程序提交审核历史版本记录从哪里查看
谷歌数据中心发生“电力事故”造成 3 人受伤
Short video software development - how to break the platform homogenization
学长告诉我,大厂MySQL都是通过SSH连接的
【勇敢饭饭,不怕刷题之链表】链表反转的几种情况
用proteus直接仿真stm32-可以完全丢弃编程器
ISO9001在讲什么?过程方法和风险思维
建校仅11年就入选“双一流” ,这所高校是凭什么做到的?
JWT implements login authentication + Token automatic renewal scheme
Several small projects that I have open sourced over the years
力扣练习——64 最长和谐子序列
力扣练习——58 验证二叉搜索树
第5章相似矩阵及二次型(4)
Research on motion capture system for indoor combined positioning technology
mysql5.7 installation and deployment - yum installation
Get started quickly and conquer three different distributed architecture calling schemes
力扣练习——61 根据字符出现频率排序
内存问题难定位,那是因为你没用ASAN
零基础想自学软件测试,有没有大佬可以分享下接下来的学习书籍和路线?









