Leetcode刷题Python34. 在排序数组中查找元素的第一个和最后一个位置(二分查找)
Posted Better Bench
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode刷题Python34. 在排序数组中查找元素的第一个和最后一个位置(二分查找)相关的知识,希望对你有一定的参考价值。
1 题目
给你一个按照非递减顺序排列的整数数组 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]
2 解析
(1)方法一
两次二分查找
第一次查找起始位置:
1、二分的范围,l = 0l=0, r = nums.size() - 1r=nums.size()−1,我们去二分查找>=target>=target的最左边界。
2、当nums[mid] >= targetnums[mid]>=target时,往左半区域找,r = midr=mid。
3、当nums[mid] < targetnums[mid]<target时, 往右半区域找,l = mid + 1l=mid+1。
4、如果nums[r] != targetnums[r]!=target,说明数组中不存在目标值 targettarget,返回 [-1, -1][−1,−1]。否则我们就找到了第一个>=target>=target的位置LL。
第二次查找结束位置:
1、二分的范围,l = 0l=0, r = nums.size() - 1r=nums.size()−1,我们去二分查找<=target<=target的最右边界。
2、当nums[mid] <= targetnums[mid]<=target时,往右半区域找,l = midl=mid。
3、当nums[mid] > targetnums[mid]>target时, 往左半区域找,r = mid - 1r=mid−1。
4、找到了最后一个<=target<=target的位置RR,返回区间[L,R][L,R]即可。
二分查找的模板及使用方法
模板1
当我们将区间[l, r][l,r]划分成[l, mid][l,mid]和[mid + 1, r][mid+1,r]时,其更新操作是r = midr=mid或者l = mid + 1l=mid+1,计算midmid时不需要加11,即mid = (l + r)/2mid=(l+r)/2。
代码模板:
def bsearch_1( l, r):
while (l < r)
mid = (l + r)/2;
if (check(mid)):
r = mid
else:
l = mid + 1;
return l;
模板2
当我们将区间[l, r][l,r]划分成[l, mid - 1][l,mid−1]和[mid, r][mid,r]时,其更新操作是r = mid - 1r=mid−1或者l = midl=mid,此时为了防止死循环,计算midmid时需要加11,即mid = ( l + r + 1 ) /2mid=(l+r+1)/2。
代码模板:
def bsearch_2( l, r)
while (l < r)
mid = ( l + r + 1 ) /2
if (check(mid)):
l = mid;
else:
r = mid - 1;
return l;
(2)方法二
利用Python的返回索引的方法list.index()
第一次正序,第二次逆序
3 Python实现
(1)方法一
def searchRange(self, nums: List[int], target: int) -> List[int]:
# 方法一:两个二分查找
if target not in nums:
return [-1,-1]
l = 0
r = len(nums)-1
while l<r:
mid = int((l+r)/2)
if nums[mid]>=target:
r = mid
else :
l = mid+1
if nums[r] !=target:return [-1,-1]
L = l
l,r = 0,len(nums)-1
while l < r:
mid = int((l+r+1)/2)
if nums[mid] <= target:
l = mid
else:
r = mid-1
return [L,r]
(2)方法二
def searchRange(self, nums: List[int], target: int) -> List[int]:
# 方法二:两次顺序遍历
if target not in nums:
return [-1,-1]
start = nums.index(target)
nums.reverse()
end = len(nums)-nums.index(target)-1
return [start,end]
以上是关于Leetcode刷题Python34. 在排序数组中查找元素的第一个和最后一个位置(二分查找)的主要内容,如果未能解决你的问题,请参考以下文章
leetcode刷题删除排序数组中的重复项removeDuplicates(Python)
leetcode刷题删除排序数组中的重复项removeDuplicates(Python)
Leetcode刷题Python剑指 Offer 04. 二维数组中的查找