难度: Medium
原题连接
内容描述
Given an array of integers nums sorted in ascending order, find the starting and ending position of a given target value.
Your algorithm's runtime complexity must be in the order of O(log n).
If the target is not found in the array, return [-1, -1].
Example 1:
Input: nums = [5,7,7,8,8,10], target = 8
Output: [3,4]
Example 2:
Input: nums = [5,7,7,8,8,10], target = 6
Output: [-1,-1]
思路 1 - 时间复杂度: O(lgN)- 空间复杂度: O(1)******
二分法,先找target
出现的左边界,判断是否有target
后再判断右边界
- 找左边界:二分,找到一个
index
- 该
index
对应的值为target
- 并且它左边
index-1
对应的值不是target
(如果index
为0
则不需要判断此条件) - 如果存在
index
就将其append
到res
中
- 该
- 判断此时
res
是否为空,如果为空,说明压根不存在target
,返回[-1, -1]
- 找右边界:二分,找到一个
index
(但是此时用于二分循环的l
可以保持不变,r
重置为len(nums)-1
,这样程序可以更快一些)- 该
index
对应的值为target
- 并且它右边
index+1
对应的值不是target
(如果index
为len(nums)-1
则不需要判断此条件) - 如果存在
index
就将其append
到res
中
- 该
AC 代码
class Solution:
def searchRange(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
if not nums or len(nums) == 0:
return [-1, -1]
res = []
l, r = 0, len(nums)-1
# search for left bound
while l <= r:
mid = l + ((r - l) >> 2)
if nums[mid] == target and (mid == 0 or nums[mid-1] != target):
res.append(mid)
break
elif nums[mid] < target:
l = mid + 1
else:
r = mid - 1
if not res:
return [-1, -1]
# search for right bound, now we don't need to reset left pointer
r = len(nums)-1
while l <= r:
mid = l + ((r - l) >> 2)
if nums[mid] == target and (mid == len(nums)-1 or nums[mid+1] != target):
res.append(mid)
break
elif nums[mid] > target:
r = mid - 1
else:
l = mid + 1
# 这里直接返回res是因为前面如果判断左边界没返回的话就说明我们判断右边界的时候一定会append元素
return res
思路 2 - 时间复杂度: O(lgN)- 空间复杂度: O(1)******
跟第35题一样的思路,先找到第一个大于等于target的值的index,再找到最后一个小于等于target的值的index,然后做一些边界判断,就可以了。
class Solution(object):
def searchRange(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
if not nums or len(nums) == 0:
return [-1, -1]
res = []
l, r = 0, len(nums) - 1
while l <= r:
mid = l + ((r-l) >> 1)
if nums[mid] < target:
l = mid + 1
else:
r = mid - 1
if l <= len(nums) - 1:
if nums[l] != target:
return [-1, -1]
else:
res.append(l)
else:
if nums[l-1] != target:
return [-1, -1]
else:
res.append(l-1)
r = len(nums) - 1
while l <= r:
mid = l + ((r-l) >> 1)
if nums[mid] > target:
r = mid - 1
else:
l = mid + 1
if r >= 0:
if nums[r] != target:
res.append(-1)
else:
res.append(r)
else:
if nums[r+1] != target:
res.append(-1)
else:
res.append(r+1)
return res