一:题目
给定一个按照升序排列的整数数组 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]
二:思路
思路:1.我们求取给定数组范围内 目标值的左边界和右边界 2.拿下方的例子来解释: nums = [5,7,7,8,8,10], target = 8 3.左边界指的就是数组当中的元素值都小于等于目标值的范围:5,7,7,8 右边界:指的是数组当中的元素值都大于等于目标值的范围:8,10 4.当我们求出目标值的左右边界,也就求出了题目说的开始和结束位置
三:上码
方法一:二分法
class Solution {
public:
vector<int> searchRange(vector<int>& v, int target) {
int l = left_border(v,target);
int r = right_border(v,target);
if(l == -3 || r == -3){
return {-1,-1};
}
if(v[l+1] == target && v[r-1] == target)
return {l+1,r-1};
return{-1,-1};
}
int left_border(vector<int>& v, int target){
int l = 0;
int r = v.size() - 1;
int mid;
int temp = -3;
while(l <= r){
mid = (l+r)/2;
if(v[mid] >= target){
r = mid - 1;
temp = r;
}else{
l = mid + 1;
}
}
return temp;
}
int right_border(vector<int>& v, int target){
int l = 0;
int r = v.size() - 1;
int mid;
int temp = -3;
while(l <= r){
mid = (l+r)/2;
if(v[mid] > target){
r = mid - 1;
}else{
l = mid + 1;
temp = l;
}
}
return temp;
}
};
方法二:调用库函数lower_bound,upper_bound
注意调用库函数的区别:
lower_bound(开始位置,结束位置,目标值) - 开始位置 : 这个返回的是元素第一次出现的位置(如果查询不到目标值则返回第一个比起大的元素下标) upper_bound(开始位置,结束位置,目标值) - 开始位置 :这个返回的是有元素第一次大于目标值的位置,所以在本题中 要减一
注意这是升序数组当中调用的函数
我自己在测试用例时,用了个非升序的例子,害。。。。。。结果。。省略一万句。。。
class Solution {
public:
vector<int> searchRange(vector<int>& v, int target) {
int l = lower_bound(v.begin(),v.end(),target) - v.begin();
if( l == v.size() || v[l] != target){
return {-1,-1};
}
int r = upper_bound(v.begin(),v.end(),target) - v.begin();
return {l,r-1};
}
};
四:补充vector中lower_bound(),upper_bound()的用法测试用例
#include<bits/stdc++.h>
using namespace std;
int main(){
vector<int>v;
int N,a;
cin >> N >> a ;
for(int i = 0; i < N; i++){
int temp;
cin >> temp;
v.push_back(temp);
}
int l = lower_bound(v.begin(),v.end(),a) - v.begin();
int r = upper_bound(v.begin(),v.end(),a) - v.begin();
cout << l << " " << r - 1;
}
拿走不用谢!!
最后在啰嗦啰嗦,最好不要用库函数,这道题,其实就是考察二分法的运用,对于这个库函数其实知道就行,可以将他用到你写的其他码上,本题不建议使用!!
好了 就这样!!加油 BOY!!! and girl!!!!!!!!!
|