一.問題描述
Given a sorted array of integers, 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]
.
For example,
Given [5, 7, 7, 8, 8, 10]
and target value 8,
return [3, 4]
.
二.代碼編寫
對於有序序列,需求是對數時間複雜度的問題,第一反應就是二分法,對於這種有多個要求輸出的問題,與經典的二分查找的不同就在於判斷條件多了許多,代碼編寫的時候要非常細緻,比如在while大循環的判斷條件上,邊界是大於等於,而非大於。因爲要找到兩端的兩個target的值,所以會有兩個左右指針,在指針移動時也要注意細節。這一題可以用迭代的思想來完成,會使代碼不顯得這麼冗長,但效率上就不見得優於直接手寫了。代碼如下:
class Solution(object):
def searchRange(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
len_nums = len(nums)
left1=left2 = 0 # 定義兩個指針對(left1,right1)和(left2,right2)
right1=right2 = len_nums-1
rlist = [-1,-1]
while left1<=right1 or left2<=right2:
if left1==left2 and right1 == right2: # 當兩個指針對相同時
mid = (left1+right1)/2
if nums[mid]>target:
right1=right2=mid-1
elif nums[mid]<target:
left1=left2=mid+1
else:
if mid>0 and nums[mid-1]==target:
right1=mid-1 # 前指針對繼續左移
else:
rlist[0] = mid
left1=-1 # 找到前target後立flag,以免後面代碼繼續找
right1=-2
if mid<len_nums-1 and nums[mid+1]==target:
left2 = mid+1
else:
rlist[1]=mid
left2=-3 # 找到後target後立flag,以免後面代碼繼續找
right2=-4
elif left1 != -1: # 兩個指針對不同且前指針對未找到最左邊的target
mid1 = (left1+right1)/2
if nums[mid1]<target:
left1=mid1+1
elif nums[mid1]>target:
right1 = mid1-1
elif mid1>0 and nums[mid1-1]==target:
right1 = mid1-1
else:
rlist[0] = mid1
left1=-1
right1=-2
elif left2 != -3: # 兩個指針對不同且後指針對未找到最右邊的target
mid2 = (left2+right2)/2
if nums[mid2]<target:
left2 = mid2+1
elif nums[mid2]>target:
right2 = mid2-1
elif mid2<len_nums-1 and nums[mid2+1]==target:
left2=mid2+1
else:
rlist[1]=mid2
left2=-3
right2=-4
return rlist
運行時間: