二分与排序中等1 种解法
#34在排序数组中查找元素的第一个和最后一个位置
在非递减数组中返回 target 的起止下标,不存在时返回 [-1, -1]。
#数组#二分查找
解题主线
01
分别查找第一个不小于 target 和第一个大于 target 的位置,区间即 [lower, upper - 1]。
解法 1:两次下界二分
用统一 lowerBound 分别定位 target 与 target + 1 的边界;为避免 target + 1 溢出,第二次按严格大于查找。
时间复杂度
O(log n)
空间复杂度
O(1)
java
final class Solution {
public int[] searchRange(int[] nums, int target) {
int first = lowerBound(nums, target);
if (first == nums.length || nums[first] != target) return new int[] {-1, -1};
int last = upperBound(nums, target) - 1;
return new int[] {first, last};
}
private int lowerBound(int[] nums, int target) {
int left = 0, right = nums.length;
while (left < right) {
int middle = left + (right - left) / 2;
if (nums[middle] < target) left = middle + 1;
else right = middle;
}
return left;
}
private int upperBound(int[] nums, int target) {
int left = 0, right = nums.length;
while (left < right) {
int middle = left + (right - left) / 2;
if (nums[middle] <= target) left = middle + 1;
else right = middle;
}
return left;
}
}用统一 lowerBound 分别定位 target 与 target + 1 的边界;为避免 target + 1 溢出,第二次按严格大于查找。
边界与易错点
- lower 可能等于数组长度,读取 nums[lower] 前必须检查。
- 找到一次 target 后不能立即结束,边界仍可能在同侧更远处。
整理来源
由旧仓库源码复核、去重并整理;展示代码已按 Java 21 语义修正明显问题。
medium/Q034_search_first_last.java