給定一個按升序排列的整數數組 nums 和目標值 target,找出目標值在數組中的起始和結束位置。要求時間複雜度 O(log n)。若目標值不存在,返回 [-1, -1]。
範例:
輸入: nums = [5,7,7,8,8,10], target = 8
輸出: [3, 4]
利用有序性,分別查找左邊界(第一個 ≥ target 的位置)和右邊界(第一個 > target 的位置 - 1):
mid 指向值 ≥ target 時向左縮,否則向右mid 指向值 > target 時向左縮,否則向右[-1, -1]時間複雜度:O(log n),空間複雜度:O(1)。
public class Solution {
public int[] searchRange(int[] nums, int target) {
int[] result = {-1, -1};
int n = nums.length;
if (n == 0) return result;
// 查找左邊界:第一個 >= target 的位置
int left = 0, right = n - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] >= target) {
right = mid - 1;
} else {
left = mid + 1;
}
}
int start = left;
// 目標不存在
if (start == n || nums[start] != target) {
return result;
}
// 查找右邊界:第一個 > target 的位置 - 1
left = 0; right = n - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] > target) {
right = mid - 1;
} else {
left = mid + 1;
}
}
int end = right;
result[0] = start;
result[1] = end;
return result;
}
}
class Solution:
def searchRange(self, nums, target):
def lower_bound(arr, val):
l, r = 0, len(arr)
while l < r:
mid = (l + r) // 2
if arr[mid] >= val:
r = mid
else:
l = mid + 1
return l
start = lower_bound(nums, target)
if start == len(nums) or nums[start] != target:
return [-1, -1]
end = lower_bound(nums, target + 1) - 1
return [start, end]
[left, right) 統一邊界處理,避免死循環這道題是二分查找邊界問題的標準範例,理解「第一個 ≥」與「第一個 >」的區別是關鍵。