剑指 Offer 53 - I. 在排序数组中查找数字 I
个人思路
题目条件:数组已排好序,因此下意识就要想到二分查找
思路一
- 使用lower_bound(),找到第一个大于等于target的元素
- 若元素不等于target,说明target在数组中不存在,返回0
- 若元素等于target,则向后顺序遍历与target相等的元素,统计target的个数
思路一注意
- 向后顺序遍历的过程中,注意数组访问不要越界
- 注意当数组长度为0的特例
思路二
- 使用两次二分查找,分别找出第一个target元素和最后一个target元素,计算出target的元素个数
- 较易理解的二分查找(与lower_bound相比):(查找第一个target元素为例)当中间元素等于target时,判断中间元素的前一个元素是否也是target
- 如果也是target,说明第一个target在左半段
- 如果不是,说明此处就是第一个target
思路二注意
- 在判断中间元素的前一个元素是否也等于target时,由于是通过nums[mid - 1]访问,所以要判断访问是否越界
个人思路代码
思路一
class Solution {
public:
int search(vector<int>& nums, int target) {
if(nums.size() == 0){
return 0;
}
int left = 0, right = nums.size() - 1;
while(left < right){
int mid = (left + right) >> 1;
if(nums[mid] >= target){
right = mid;
}else{
left = mid + 1;
}
}
int ans = 0;
if(nums[left] != target){
return ans;
}
int index = left;
while(index < nums.size() && nums[left] == nums[index]){
ans++;
index++;
}
return ans;
}
};
思路二
class Solution {
public:
int getFirst(vector<int>& nums, int target){
int left = 0, right = nums.size() - 1;
while(left <= right){
int mid = (left + right) >> 1;
if(nums[mid] > target){
right = mid - 1;
}else if(nums[mid] < target){
left = mid + 1;
}else{
if((mid > 0 && target != nums[mid - 1]) || mid == 0){//是第一个target
return mid;
}else{
right = mid - 1;
}
}
}
return -1;
}
int getLast(vector<int>& nums, int target){
int left = 0, right = nums.size() - 1;
while(left <= right){
int mid = (left + right) >> 1;
if(nums[mid] > target){
right = mid - 1;
}else if(nums[mid] < target){
left = mid + 1;
}else{
//cout << left << " " << mid << " " << right << endl;
if((mid < nums.size() - 1 && target != nums[mid + 1]) || mid == nums.size() - 1){//是最后一个target
return mid;
}else{
left = mid + 1;
}
}
//cout << left << " " << mid << " " << right << endl;
}
return -1;
}
int search(vector<int>& nums, int target) {
if(nums.size() == 0){
return 0;
}
int ans = 0;
int first = getFirst(nums, target);
int last = getLast(nums, target);
if(first != -1 && last != -1){
ans = last - first + 1;
}
//cout << first << " " << last << endl;
return ans;
}
};