難度:中等
給定一個按照升序排列的整數數組 nums,和一個目標值 target。找出給定目標值在數組中的開始位置和結束位置。
你的算法時間複雜度必須是 O(log n) 級別。
如果數組中不存在目標值,返回 [-1, -1]。
示例 1:
輸入: nums = [5,7,7,8,8,10], target = 8
輸出: [3,4]
示例 2:
輸入: nums = [5,7,7,8,8,10], target = 6
輸出: [-1,-1]
思路:因爲有時間複雜度的要求,所以需要二分法來完成,這個主要牽扯到一個邊界尋找問題,即二分法查找目標數的左邊界和有邊界,詳細請看代碼中註釋即可。同時提供一個普通遍歷查找的方法,即設置標記量flag=0,如果找到了且flag=0,則改變標記了,並且記錄此時位置(數組兩個數字均記錄,防止僅一個的情況)然後再次查詢到時更改數組第二個數字,最後數組記錄的即答案所求位置
代碼1(二分法,打敗80%+):
class Solution(object):
def searchRange(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
if len(nums)==0:
return [-1,-1]
#默認-1,-1
left,right = -1,-1
#找左邊界
start,end =0,len(nums)-1
while start+1<end:
mid=start+((end-start)/2)
#只要是中間軸大於大於等於目標值,則end左移,結果一定卡在左邊界上
if nums[mid]>=target:
end=mid
else:
start=mid
#此時可能保留兩個數 不一定誰是左邊界,所以都判斷一下,也可能都是,這樣start後判斷即可
if target==nums[end]:
left=end
if target==nums[start]:
left=start
#找有邊界
start,end=0,len(nums)-1
while start+1<end:
#同理
mid=start+((end-start)/2)
if nums[mid]<=target:
start=mid
else:
end=mid
#同上,此時需要end後判斷
if target==nums[start]:
right=start
if target==nums[end]:
right=end
return [left,right]
代碼2(普遍遍歷法,打敗70%+):
class Solution(object):
def searchRange(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
if len(nums)==0:
return [-1,-1]
flag=0
list1=[-1,-1]
for i in range(len(nums)):
if nums[i]==target:
if flag==0:
flag=1
list1[0],list1[1]=i,i
else:
list1[1]=i;
return list1