「优选算法刷题」:在排序数组中查找元素的第一个和最后一个位置

一、题目

给你一个按照非递减顺序排列的整数数组 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]

二、思路解析

找元素的题,一般都可以用 二分查找 来解决,本质也就是利用双指针。

而这道题比较刁钻一点啊,要求我们用时间复杂度为 O(log n) 的算法解决,所以暴力解法肯定是不行的。

那我们再看题目,要求的是一个区间,而不单单是一个元素,因此我们的二分查找还要实现两次,一次找左区间,也就是第一个值为 target 的位置,另一次是找第一个大于 target 的位置减一。

具体实现请看下面代码

三、完整代码

class Solution {
    public int[] searchRange(int[] nums, int target) {
        int ret[] = new int[2];
        ret[0] = ret[1] = -1;

        // 处理边界情况
        if(nums.length == 0){
            return ret;
            }

        // 1. ⼆分左端点    
        int left = 0;
        int right = nums.length - 1;
        while(left < right){
            int mid = left + (right - left) / 2;
            if(nums[mid] < target){
                left = mid + 1; 
            }else{
                right = mid;
            }
        }

        // 判断是否有结果
        if(nums[left] != target){
            return ret;
        }else{
            ret[0] = left;
        }

        // 2. ⼆分右端点
        left = 0;
        right = nums.length - 1;
        while(left < right){
            int mid = left + (right - left + 1) / 2;
            if(nums[mid] <= target){
                left = mid;
            }else{
                right = mid - 1;
            }
        }
        ret[1] = right;
        return ret ;
    }
}

以上就是本篇博客的全部内容啦,如有不足之处,还请各位指出,期待能和各位一起进步!

你可能感兴趣的:(详解算法题,算法,数据结构,leetcode,链表,贪心算法,职场和发展,机器学习)