二分与排序中等1 种解法

#34在排序数组中查找元素的第一个和最后一个位置

在非递减数组中返回 target 的起止下标,不存在时返回 [-1, -1]。

#数组#二分查找

解题主线

01

分别查找第一个不小于 target 和第一个大于 target 的位置,区间即 [lower, upper - 1]。

解法 1两次下界二分

用统一 lowerBound 分别定位 target 与 target + 1 的边界;为避免 target + 1 溢出,第二次按严格大于查找。

时间复杂度

O(log n)

空间复杂度

O(1)

34. 在排序数组中查找元素的第一个和最后一个位置 · 两次下界二分
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