原题
Given an array of integers nums
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]
.
题目:
给定一个整数数组, 阅读按升序排序, 查找给定目标值的起始和结束位置;
算法的运行时复杂性必须是 O (log n) ;
如果在数组中找不到目标, 则返回 [-1,-1]。
Example 1:
Input: nums = [5,7,7,8,8,10], target = 8
Output: [3,4]
Example 2:
Input: nums = [5,7,7,8,8,10], target = 6
Output: [-1,-1]
My Solution
方案一
class Solution:
def searchRange(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
if not nums:
return [-1, -1]
found = False
index = start = len(nums)
end = 0
for i,count in enumerate(nums):
if target > count:
pass
elif target == count:
found = True
index = i
start = min(start, index)
end = max(end, index)
elif target < count and not found:
return [-1,-1]
if found:
return [start, end]
else:
return [-1,-1]
注:这种方式也能通过,但是其实际算法时间复杂度为O(n),因为遍历了一遍list。
Reference answer
同第33题,只是稍稍变化;看到O(logn)的时间复杂度的查找,就首先想到二分查找,刚好这道题中数字是升序的,所以可以直接拿来用,但是我们要进行一点点小修改。当我们使用传统二分查找思路找到和target相等的值的索引的时候,我们继续分头向前向后循环,直到找到不等于target的值,此时就能找到我们需要的索引对。
class Solution:
def searchRange(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
start = 0
end = len(nums) - 1
while start <= end:
mid = int((start + end)/2)
if nums[mid] == target:
left = right = mid
while left - 1 >= 0 and nums[left - 1] == target:
left -= 1
while right + 1 < len(nums) and nums[right + 1] == target:
right += 1
return [left, right]
if nums[mid] <= target:
start = mid + 1
if nums[mid] > target:
end = mid - 1
return [-1, -1]
反思:
- 迭代方案(不断调用自身)与递归方法很近似,往往可以相互转化;
- 要熟悉掌握二分法;