leetcode-34
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值 target,返回[-1, -1]。
进阶:设计并实现时间复杂度为 O(log n) 的算法
方法一:暴力解法 时间复杂度O(n),根据题意(升序排列)分别遍历找到左右边界即可。
class Solustion_1 {
public:
int findTargetLeftLocation(vector<int>& nums,int target) {
int n = nums.size();
int leftLocation = -1;
for (int i = 0; i < n; i++) {
if (nums[i] == target) {
leftLocation = i;
break;
}
}
return leftLocation;
}
int findTargetRightLocation(vector<int>& nums, int target) {
int n = nums.size();
int rightLocation = -1;
for (int j = n - 1; j >= 0; j--) {
if (nums[j] == target) {
rightLocation = j;
break;
}
}
return rightLocation;
}
};
方法二:二分查找左右边界,时间复杂度O(log n)
class Solution_2 {
public:
vector<int> findRange(vector<int>& nums, int target) {
int leftBorder = binary_FindLeftLocation(nums, target);
int rightBorder = binary_FindRightLocation(nums, target);
// 情况一 target在数组范围的左边或右边 没有改变leftBorder和rightBoder的初始值
if (leftBorder == -1 || rightBorder == -1) return { -1,-1 };
// 情况二 target在数组范围内且数组中存在等于target的值
if (rightBorder - leftBorder > 1) return { leftBorder + 1,rightBorder - 1 };
// 情况三 target在数组范围内但数组中不存在等于target的值
return { -1,-1 };
}
private:
int binary_FindLeftLocation(vector<int>& nums, int target) {
// 二分查找,寻找target的左边界(不包含target)
int left = 0;
int right = nums.size() - 1;
int leftBorder = -1;
while (left <= right) {
int middle = left + ((right - left) / 2);
if (nums[middle] >= target) {
//寻找左边界,就要在nums[middle]==target的时候更新right
right = middle - 1;
leftBorder = right;
}else{
left = middle + 1;
}
}
return leftBorder;
}
int binary_FindRightLocation(vector<int>& nums, int target) {
// 二分查找,寻找target的右边界(不包含target)
int left = 0;
int right = nums.size() - 1; // 定义target在闭区间里面
int rightBorder = -1; // 默认赋值为没有找到target
while (left <= right) {
int middle = left + ((right - left) / 2);
if (nums[middle] > target) {
right = middle - 1; // 则target所在的区间为[left,middle-1];
}
else {
//当nums[middle] == target 的时候,更新left,这样才能得到target的右边界
left = middle + 1;
rightBorder = left;
}
}
return rightBorder;
}
};