解法1:遍历一遍数组
int search(int* nums, int numsSize, int target){
if (nums == NULL || numsSize <= 0)
return 0;
if (nums[0] > target || nums[numsSize-1] < target)
return 0;
int cnt = 0;
for (int i = 0; i < numsSize; i++)
if (nums[i] == target)
cnt++;
return cnt;
}
解法2:二分查找,效率较好
int search(int* nums, int numsSize, int target){
if (nums == NULL || numsSize <= 0)
return 0;
if (nums[0] > target || nums[numsSize-1] < target) //特例判断
return 0;
int left = 0, right = numsSize - 1;
int cnt = 0;
int mid;
while (left <= right) { // <=
mid = (left + right)>>1;
if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid - 1;
} else {
cnt++;
int m = mid - 1; //mid左边计数
while (0 <= m && nums[m] == target) {
cnt++;
m--;
}
m = mid + 1; //mid右边计数
while (m < numsSize && nums[m] == target) {
cnt++;
m++;
}
break;
}
}
return cnt;
}
34. 在排序数组中查找元素的第一个和最后一个位置
题目
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
你的算法时间复杂度必须是 O(log n) 级别。
如果数组中不存在目标值,返回 [-1, -1]。
示例 1:
输入: nums = [5,7,7,8,8,10], target = 8
输出: [3,4]
示例 2:输入: nums = [5,7,7,8,8,10], target = 6
输出: [-1,-1]
解法:二分查找
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
int len = nums.size();
vector<int> res(2, -1);
if (len == 0)
return res;
/*
if (len == 1) {
if (nums[0] == target)
return vector<int>{0, 0}; //是花括号不是小括号
else
return vector<int>{-1, -1};
}
*/
int left = 0, right = len-1;
while (left <= right) { //=是处理target没有重复值情况
int mid = left + ((right - left)>>1);
if (nums[mid] > target)
right = mid - 1;
else if (nums[mid] < target)
left = mid + 1;
else {
left = mid-1; //重复利用left变量
while (left >= 0 && nums[left] == target)
--left;
res[0] = left+1;
right = mid+1; //重复利用right变量
while (right < len && nums[right] == target)
++right;
res[1] = right-1;
break;
}
}
return res;
}
};