项目场景:
在排序数组中查找元素的第一个和最后一个位置
给定一个按照升序排列的整数数组 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]
问题描述
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
int is = getNum(nums, target);
int left = -1;
int right = -1;
if (is != -1) {
for (int i = is; nums[i] == target && i >= 0; i--)
left = i;
for (int i = is; nums[i] == target && i < nums.size(); i++)
right = i;
}
return {left, right};
}
private:
int getNum(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() - 1;
while (left <= right) {
int middle = (right - left) / 2 + left;
if (nums[middle] < target) {
left = middle + 1;
} else if (nums[middle] > target) {
right = middle - 1;
} else {
return middle;
}
}
return -1;
}
};
在以上代码中一些数据测试是可以通过的,但是在 数组只有一位数 却发生了溢出。
原因分析:
我再三检查我的代码发现限定的范围并没有问题,在我的思路中也不可能发生溢出,我一度怀疑可能是由于编译器或库的已知问题导致,直到我无意间再次看到这段代码
for (int i = is; nums[i] == target && i >= 0; i--)
left = i;
for (int i = is; nums[i] == target && i < nums.size(); i++)
right = i;
解决方案:
直说了,调换两个判断的顺序就行了
for (int i = is; i >= 0 && nums[i] == target; i--)
left = i;
for (int j = is; j < nums.size() && nums[j] == target; j++)
right = j;
写在最后:
代码的编写中一些小的疏漏是致命的,它不易被发现,搞人心态,还浪费时间!所以基础的学习还是不容忽视的。