34 在排序陣列中查詢元素的第乙個和最後乙個位置

2021-10-06 10:53:14 字數 1769 閱讀 6600

給定乙個按照公升序排列的整數陣列 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...