給定一個按升序排序的整數數組 nums
和一個目標值 target
,請在數組中找到目標值的 第一個 和 最後一個 位置,並以一個長度為 2 的列表返回結果。如果數組中不存在目標值,返回 [-1, -1]
。
限制條件
nums
的長度範圍為 0 <= nums.length <= 10^5
。-10^9 <= nums[i] <= 10^9
。nums
保證為非遞減排序。範例1:
Input: nums = [5,7,7,8,8,10], target = 8
Output: [3,4]
範例2:
Input: nums = [5,7,7,8,8,10], target = 6
Output: [-1,-1]
範例3:
Input: nums = [], target = 0
Output: [-1,-1]
由於數組是排序的,可以利用二分搜索來高效地定位目標值的 左邊界 和 右邊界。
[-1, -1]
。class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
def findLeft(nums, target):
left, right = 0, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return left
def findRight(nums, target):
left, right = 0, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] <= target:
left = mid + 1
else:
right = mid - 1
return right
left = findLeft(nums, target)
right = findRight(nums, target)
# 確保 target 存在於數組中
if left <= right and left < len(nums) and nums[left] == target:
return [left, right]
else:
return [-1, -1]
遍歷整個數組,記錄目標值的第一次和最後一次出現的位置。該方法不符合 O(log n) 的要求,但實現簡單。
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
start, end = -1, -1
for i in range(len(nums)):
if nums[i] == target:
if start == -1:
start = i
end = i
return [start, end]
利用 Python 的內建函數 bisect
模組,分別找到目標值的左邊界和右邊界。
import bisect
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
left = bisect.bisect_left(nums, target)
right = bisect.bisect_right(nums, target) - 1
if left <= right and left < len(nums) and nums[left] == target:
return [left, right]
else:
return [-1, -1]
bisect_left
和 bisect_right
都是基於二分法。如果目標是最優解法,建議使用 解法一。