一、题目
给定一个按照升序排列的整数数组 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]
二、解题
该题和33. 搜索旋转排序数组(Swift版)很类似,只是在找到目标index后,判断左右两边的值是否也为target,并确定范围。
详细步骤见代码。
时间复杂度:O(log(n))。空间复杂度:O(1)。
三、代码实现
class Solution {
func searchRange(_ nums: [Int], _ target: Int) -> [Int] {
var left = 0
var right = nums.count - 1
var index = -1
while left <= right && index == -1 {
// 当前居中的位置
let mid = (right + left) / 2
if nums[mid] == target {// 循环执行,知道找到nums[mid] == target,然后返回mid
index = mid
}
// 如果nums[mid] < nums[right]说明,mid->right是有序的
if nums[mid] < nums[right] {
// 如果target在nums[mid]与nums[right]之间,left向右移动至mid+1
if nums[mid] < target && target <= nums[right] {
left = mid + 1
}else {// 否则right向左移动至mid-1
right = mid - 1
}
}else{// 否则说明left->mid是有序的
// 如果target在nums[left]与nums[right]之间,right向左移动至mid-1
if nums[left] <= target && target < nums[mid] {
right = mid - 1
}else{// 否则left向左移动至mid+1
left = mid + 1
}
}
}
var leftIndex = index
var rightIndex = index
for _ in nums {
// index的左边是否等于target
let hasLeft = leftIndex - 1 > -1 && nums[leftIndex - 1] == target
// index的右边是否等于target
let hasRight = rightIndex + 1 < nums.count && nums[rightIndex + 1] == target
if hasLeft {
leftIndex -= 1
}
if hasRight {
rightIndex += 1
}
// 如果左右都没有target,停止遍历
if !hasLeft && !hasRight {
break
}
}
return [leftIndex, rightIndex]
}
}
Demo地址:github