LeetCode:寻找范围

来源:互联网 发布:杨米尔斯理论 知乎 编辑:程序博客网 时间:2024/06/13 05:13

题目描述:给定一个有序数组(如[5, 7, 7, 8, 8, 10]),以及一个目标值(target=8),找出这个目标值在数组中的范围(结果是[3,4]),要求的时间复杂度为O(logN),N表示数组的长度。

1、递归解法:比较中间元素(下标为mid)与target的大小,可能出现三种情况,即中间元素等于 target,中间元素小于 target,中间元素大于 target,下面我们分情况讨论:

情况1:nums[mid]==target,则[left, right]中的left可能在序列的前半段中,right可能在序列的后半段,接下来我们可以解决原问题的两个子问题:

子问题1在序列的前半段中找[left_1,right_1],这个left_1一定是最终的left,而right_1一定等于前面的mid;

子问题2在序列的后半段中找[left_2,right_2],这个right_2一定是最终的right,而left_2一定等于前面的mid;

待两个子问题解决后,原问题的解就是[left_1, right_2];

情况2:nums[mid] < target,则[left,right]一定在半段序列中,所以我们只需解决子问题2,得到的结果就是原问题的结果;

情况3:nums[mid] > target,则[left,right]一定在半段序列中,所以我们只需解决子问题1,得到的结果就是原问题的结果;

代码如下:

vector<int> searchRange(vector<int>& nums, int target) {        vector<int> res;        int size = nums.size();        int s = size, e = -1;        searchRange(nums,target,0,size-1,s,e);        if(s==size && e==-1) {            res.push_back(-1);            res.push_back(-1);            return res;        }        else{            res.push_back(s);            res.push_back(e);            return res;        }}void searchRange(vector<int>& nums, int &target, int low,int high,int &s,int &e){        // s代表left, e代表right        if(low>high) return ;        int mid = (low+high)/2;        if(nums[mid]==target){            searchRange(nums,target,low,mid-1,s,e);            searchRange(nums,target,mid+1,high,s,e);            s = mid<s? mid:s;            e = mid>e? mid:e;        }        else if(nums[mid]<target){            searchRange(nums,target,mid+1,high,s,e);        }        else            searchRange(nums,target,low,mid-1,s,e);}

2、迭代解法,这个更直观一点,先找left,再找right,代码如下:

vector<int> searchRange(vector<int>& nums, int target) {    int start = 0, end = nums.size(), mid, left, right;    while (start < end) {        mid = (start + end) / 2;        if (nums[mid] >= target)            end = mid;        else            start = mid + 1;    }    left = start; // 找到了left    start = 0, end = nums.size();    while (start < end) {        mid = (start + end) / 2;        if (nums[mid] > target)            end = mid;        else            start = mid + 1;    }    right = start;// 找到了right    return left == right ? vector<int> {-1,-1} : vector<int> {left,right-1};}
1 0
原创粉丝点击