34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣(LeetCode) (leetcode-cn.com)
1.双指针
class Solution(object):
def searchRange(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
left,right=0,len(nums)-1
res=[]
while left<right:
if nums[left]==target and nums[right]==target:
return [left,right]
if nums[left]<target:
left+=1
if nums[right]>target:
right-=1
if left<len(nums) and nums[left]==target:
return [left,left]
elif right>0 and nums[right]==target:
return [right,right]
else:
return [-1,-1]
2.两次二分查找
时间复杂度:2log(n) 即O(logn)
空间复杂度:O(1)
找的是数不是边界,所以需要判断:
locl=-1 if nums[locl]!=target else locl locr=-1 if nums[locr]!=target else locr
class Solution(object):
def searchRight(self,nums,target):
left,right=0,len(nums)-1
locr=-1
while left<=right:
mid=left+int((right-left)/2)
if nums[mid]<target:
left=mid+1
elif nums[mid]>=target:
locr=mid
right=mid-1
locr=-1 if nums[locr]!=target else locr
return locr
def searchLeft(self,nums,target):
left,right=0,len(nums)-1
locl=-1
while left<=right:
mid=left+int((right-left)/2)
if nums[mid]<=target:
locl=mid
left=mid+1
elif nums[mid]>=target:
right=mid-1
locl=-1 if nums[locl]!=target else locl
return locl
def searchRange(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
if nums==[]:
return [-1,-1]
if target<nums[0] or target>nums[-1]:
return [-1,-1]
res1=self.searchRight(nums,target)
res2=self.searchLeft(nums,target)
return [res1,res2]
2080. 区间内查询数字的频率 - 力扣(LeetCode) (leetcode-cn.com)
1.两次二分查找
相比上一题,这里是找边界不是找数,所以不需要判断
时间复杂度:O(logn)
空间复杂度:O(n)
class RangeFreqQuery(object):
def __init__(self, arr):
"""
:type arr: List[int]
"""
self.arr=[]
self.dic={}
for i in range(len(arr)):
if arr[i] not in self.dic.keys():
self.dic[arr[i]]=[i]
else:
self.dic[arr[i]].append(i)
def searchRight(self,nums,target):
left,right=0,len(nums)-1
locr=0
while left<=right:
mid=left+int((right-left)/2)
if nums[mid]<target:
left=mid+1
elif nums[mid]>=target:
locr=mid
right=mid-1
return locr
def searchLeft(Self,nums,target):
left,right=0,len(nums)-1
locl=0
while left<=right:
mid=left+int((right-left)/2)
if nums[mid]<=target:
locl=mid
left=mid+1
elif nums[mid]>target:
right=mid-1
#locl=-1 if nums[locl]!=target else locl
return locl
def query(self, left, right, value):
"""
:type left: int
:type right: int
:type value: int
:rtype: int
"""
nums=self.dic[value] if value in self.dic.keys() else []
#left<=:left右边界
#right>=:right左边界
if nums==[]:
return 0
if left>nums[-1] or right<nums[0]:
return 0
res1=self.searchRight(nums,left)
res2=self.searchLeft(nums,right)
return res2-res1+1
# Your RangeFreqQuery object will be instantiated and called as such:
# obj = RangeFreqQuery(arr)
# param_1 = obj.query(left,right,value)