problem
Given an array of integers 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].
For example, Given [5, 7, 7, 8, 8, 10] and target value 8, return [3,
4].
分析
这个问题可以理解为二分查找的进阶版,要求查找到最小和最大的index,也就是说在查找到target之后还要对左侧和右侧的序列继续查找是否还有元素等于target。
def biSearch(arr,start,end,hkey):
#二分查找
if start > end:
return -1
mid = start + (end - start) // 2
if arr[mid] > hkey:
return biSearch(arr, start, mid - 1, hkey)
if arr[mid] < hkey:
return biSearch(arr, mid + 1, end, hkey)
return mid
def findMin(arr, start, end, hkey):
#左侧的index
ans = biSearch(arr, start, end, hkey)
while 1:
tmp = biSearch(arr, start, ans-1, hkey)
if tmp == -1:
break
else:
ans = tmp
return ans
def findMax(arr, start, end, hkey):
#右侧的index
ans = biSearch(arr, start, end, hkey)
while 1:
tmp = biSearch(arr, ans+1, end, hkey)
if tmp == -1:
break
else:
ans = tmp
return ans
class Solution(object):
def searchRange(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
n = len(nums)
return [findMin(nums, 0, n-1, target), findMax(nums, 0, n-1, target)]
solution
下面介绍一下在leetcode中的discussion中看到的一种简洁的解法,这种解法是直接在二分查找上做修改,只举查找最小的index为例,代码如下:
def findMin1(nums, target):
i = 0
j = len(nums)-1
while i < j:
mid = (i+j)//2
#一定在右侧才有nums[x]==target
if nums[mid] < target:
i = mid+1
#nums[mid] >= target,最小的index一定在左侧
else:
j = mid-1
#在退出while循环之前j-i=1,那么分析if-else两种情况,易知如果
#存在与target相等的元素一定在i
if nums[i] == target:
return i
else:
return -1