LeetCode HOT 100:在排序数组中查找元素的第一个和最后一个位置

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

题目描述:

给你一个递增数组,和一个目标值target,最终返回数组中第一次出现target和最后一次出现target的下标。如果该数组中没有target,返回[-1, -1]。如果只出现了一次target,返回的第一次和最后一次出现的下标相同。

思路:

这一题要求第一次出现target和最后一次出现target的下标。因为数组是递增的,如果能求得小于target的最大值的下标,设为start,那么start + 1下标对应的值就应该是第一次出现target的下标。然后,再用同样的方法,求得小于target + 1的最大值的下标,设为end,这个end下标就是target最后一次出现的下标,最终返回[start + 1, end]
举个例子:数组[100, 300, 300, 500, 500, 800, 1000]target500,那么start就应该是小于target的最大值的下标2,小于target + 1的最大值的下标end应该是4,所以最终返回[3, 4]

步骤:

1、先找到小于target的最大值的下标,设为start,使用二分可以实现
2、判断start + 1下标,如果等于数组长度或者start + 1下标对应的值不为target,说明数组中根本没有出现过target,直接返回[-1, -1]
3、找到小于target + 1的最大值的下标,设为end,同样二分实现
4、返回[start + 1, end]

代码:

    public int[] searchRange(int[] nums, int target) {
        if (nums == null || nums.length == 0) return new int[]{-1, -1};

        // lessMostRight得到小于target的最大值下标,如果nums中有target,该下标的下一个(+1)应该就是target的下标
        int start = lessMostRight(nums, target, 0, nums.length - 1) + 1;
        // 如果数组越界了,或者下一个下标并不是target,说明数组中没有target元素
        if (start == nums.length || nums[start] != target) return new int[]{-1, -1};

        // 得到小于 target + 1 的最大值下标,就是target的最右边下标
        int end = lessMostRight(nums, target + 1, start, nums.length - 1);
        return new int[]{start, end};
    }

    // 找到nums数组中,小于target的最右边的值的下标(因为数组不递减,也就是得到小于target的最大值下标)
    public int lessMostRight(int[] nums, int target, int start, int end) {
        int mid = 0;
        int ans = -1;
        while (start <= end) {
            mid = start + ((end - start) >> 1);

            if (nums[mid] < target) {
                start = mid + 1;
                ans = mid;
            } else {
                end = mid - 1;
            }
        }

        return ans;
    }
posted @ 2022-12-11 22:37  煜航  阅读(24)  评论(0编辑  收藏  举报