Leetcode典型题解答和分析、归纳和汇总——T34(在排序数组中查找元素的第一个和最后一个位置)

题目描述:

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

要求:算法的复杂度必须为O(logn) 级别,如果不存在,则返回【-1,-1】.

题目解析:
看到题目给出的复杂度要求,自然就会想到采用二分查找算法。这个算法的基本模板代码如下:

int binarySearch(int[] nums, int target) {
    int left = 0, right = ...;   //初始化左右值

    while(...) {
        int mid = (right + left) / 2;  //中间值计算
        if (nums[mid] == target) {
            ...
        } else if (nums[mid] < target) {  //全部都采用else if 形式,而不采用else
            left = ...
        } else if (nums[mid] > target) {
            right = ...
        }
    }
    return ...;
}

本题采用二分查找的办法,首先查找目标元素的左位置值,令res[0]=left, 然后再查找右值res[1] = right。注意第二次的初始left就是第一次查找过程中的res[0]的位置值。

class Solution{
    public:vector<int> searchRange(vector<int>& nums, int target){
        vector<int> res ={-1,-1};
        int len = nums.size();
        if(len==0)  return res;
        int left =0, right =len-1;
        //超出索引的范围
        if(nums[left]>target) return res;
        if(nums[right]<target) return res;  

        while(left<right) //先查找出元素的第一个位置
        {
            int mid = left+(right-left)/2;
            if(nums[mid]>=target) right=mid;
            else left=mid+1;
        }
        if(nums[left]==target) res[0]=left;  //表示已经找到了

        right = len;  //重新查找第二个目标数的位置,设置为len长度

        while(left<right)
        {
            int mid = left+(right-left)/2;  //取中间值
            if(nums[mid]>target) right =mid;
            else left = mid+1;
        }

        if(nums[left-1]==target) res[1] = left-1;

        return res;
            
    }
};

同一个程序执行,每执行一次,显示的执行时间和消耗内存都存在一定的差异,这个问题与LEETCODE内部运行处理机制存在很大关联,这应该也是一个bug。

发布了56 篇原创文章 · 获赞 7 · 访问量 4481

猜你喜欢

转载自blog.csdn.net/weixin_44504987/article/details/104343672