給定乙個按照公升序排列的整數陣列 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]
思路
看到這道題很容易想到使用二分查詢
但是難點在於,不僅要找到這個值的下標,還要找起始下標和終結下標
其實單純使用兩個二分查詢即可,乙個找起始下標,乙個找最終下標
你可能會疑惑,這樣會不會造成太多冗餘計算?
但實際上,o(logn)和o(2logn)是相等的,都是o(logn)的時間複雜度。
所以使用兩次二分查詢的方式可以減少你的思考方式,同時不會增加複雜度。
二分查詢細節
首先初始化l,r,左右指標
迴圈條件設為當l取中值,取中左還是中右,這就需要看情況了。
如果我們想要找值的起始下標,那麼當mid對應值大於這個值或者哪怕當找到這個值的時候,右邊界都要縮小
即當nums[mid] >= target的時候,r = mid
同時要注意不能以mid-1這樣的形式縮小,否則當找到這個起始下標的時候還得再減1,就不對了。
因為不可以左右兩個都=mid,必須有乙個=mid+1,否則會陷入死迴圈。
所以在其他情況下,左邊界等於mid + 1
同時,mid取左中還是右中,要以你選擇哪個是mid+1來定。這裡我們選了mid+1的是左邊,所以我們要取左中值。否則會陷入死迴圈。
所以可以這樣寫出**
while l < r:
mid =
(l + r)//2
if nums[mid]
>= target:
r = mid
else
: l = mid +
1
對於取結束下標,也是如此。
class
solution
:def
searchrange
(self, nums, target)
:# 取起始下標
l, r =0,
len(nums)-1
while l < r:
mid =
(l + r)//2
if nums[mid]
>= target:
r = mid
else
: l = mid +
1# 沒找到
ifnot nums or nums[l]
!= target:
return[-
1,-1
]# 取結束下標
a, b = l,
len(nums)-1
while a < b:
mid =
(a + b +1)
//2if nums[mid]
<= target:
a = mid
else
: b = mid -
1return
[l,a]
34 在排序陣列中查詢元素的第乙個和最後乙個位置
給定乙個按照公升序排列的整數陣列nums,和乙個目標值target。找出給定目標值在陣列中的開始位置和結束位置。你的演算法時間複雜度必須是o log n 級別。如果陣列中不存在目標值,返回 1,1 輸入 nums 5,7,7,8,8,10 target 8 輸出 3,4 輸入 nums 5,7,7,...
34 在排序陣列中查詢元素的第乙個和最後乙個位置
給定乙個按照公升序排列的整數陣列nums,和乙個目標值target。找出給定目標值在陣列中的開始位置和結束位置。你的演算法時間複雜度必須是 o log n 級別。如果陣列中不存在目標值,返回 1,1 示例 1 輸入 nums 5,7,7,8,8,10 target 8輸出 3,4 示例 2 輸入 n...
34 在排序陣列中查詢元素的第乙個和最後乙個位置
給定乙個按照公升序排列的整數陣列nums,和乙個目標值target。找出給定目標值在陣列中的開始位置和結束位置。你的演算法時間複雜度必須是 o log n 級別。如果陣列中不存在目標值,返回 1,1 示例 1 輸入 nums 5,7,7,8,8,10 target 8輸出 3,4 示例 2 輸入 n...