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

题目

给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。

如果数组中不存在目标值 target,返回 [-1, -1]。

进阶:

你可以设计并实现时间复杂度为 O(log n) 的算法解决此问题吗?

示例 1:

输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]

示例 2:

输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]

示例 3:

输入:nums = [], target = 0
输出:[-1,-1]

提示:

0 <= nums.length <= 10^5
-10^9 <= nums[i] <= 10^9
nums 是一个非递减数组
-10^9 <= target <= 10^9

思路

暴力解法就不写了,for循环从头/尾遍历即可。而进阶的解法,看到有序数组找某个值对应的下标,第一反应就是二分查找,而这个题目比较特别,要求找第一个位置low和最后一个位置high,但是换个思路,low其实就是求第一个大于等于target的下标,而high就是求第一个小于等于target的下标,然后我们只要检查这两个下标是否满足 low<=high ,如果不满足,说明数组没有等于target的值,返回 [-1,-1]。

AC代码

点击查看代码
class Solution {
    private int b_search_low(int[] nums, int low, int high, int target) {
        while( low <= high ) {
            int mid = (low+high)/2;
            if( nums[mid]>=target) {
                high = mid -1;
            } else {
                low = mid+1;
            }
        }
        return low;
    }

    private int b_search_high(int[] nums, int low, int high, int target) {
        while( low <= high ) {
            int mid = (low+high)/2;
            if( nums[mid]<=target) {
                low = mid +1;
            } else {
                high = mid - 1 ;
            }
        }
        return high;
    }

    public int[] searchRange(int[] nums, int target) {
        int len = nums.length;
        if( nums.length == 0) {
            return new int[]{-1, -1};
        }
        int low = b_search_low(nums, 0, len-1, target);
        int high = b_search_high(nums, 0, len-1, target);
        if( low>high ) {
            return new int[]{-1, -1};
        }
        return new int[]{low, high};
    }
}
posted @ 2022-05-07 20:45  Asimple  阅读(19)  评论(0编辑  收藏  举报