class Solution {
public int countTarget(int[] scores, int target) {
// 1. 搜索右边界 right
int i = 0, j = scores.length - 1;
while (i <= j) {
int mid = (i+j) / 2;
if (scores[mid] <= target) {
i = mid + 1;
} else {
j = mid - 1;
}
}
int right = i;
// 若数组中没有target,则提前返回
if (j >= 0 && scores[j] != target) return 0;
// 2. 搜索左边界
i = 0; j = scores.length - 1;
while (i <= j) {
int mid = (i+j) / 2;
if (scores[mid] < target) {
i = mid + 1;
} else {
j = mid - 1;
}
}
int left = j;
return right - left - 1;
}
}
class Solution {
public int countTarget(int[] scores, int target) {
int left=first(scores,target);
int right=last(scores,target);
if(left<0||right<0) return 0;
return right-left+1;
}
//找到第一个等于target的下标
public int first(int[] scores, int target){
if(scores==null||scores.length<=0)
return -1;
int l=0;
int r=scores.length-1;
while(l=target){
r=mid;
}
}
if(scores[l]!=target)return -1;
return l;
}
//找到最后一个等于target的下标
public int last(int[] scores,int target){
if(scores==null||scores.length<=0)
return -1;
int l=0;
int r=scores.length-1;
while(ltarget){
r=mid-1;
}else if(scores[mid]<=target)
l=mid;
}
if(scores[l]!=target) return -1;
return l;
}
}
class Solution {
public:
int countTarget(vector& scores, int target) {
if(scores.empty()){
return 0;
}
int l = findl(scores, target);
int r = findr(scores, target);
if (l == -1 && r == -1){
return scores.size();
}
if (l == -1){
return r;
}
if (r == -1){
return scores.size() - l - 1;
}
return r - l - 1;
}
int findl(vector& v, int target) {
int l = 0;
int r = v.size() - 1;
if (v[l] >= target) {
return -1;
}
while (l < r) {
int mid = (r - l + 1) / 2 + l;
if (v[mid] >= target) {
r = mid - 1;
}
else {
l = mid;
}
}
return l;
}
int findr(vector& scores, int target) {
int l = 0;
int r = scores.size() - 1;
if (scores[r] <= target) {
return -1;
}
while (l < r) {
int mid = (r - l) / 2 + l;
if (scores[mid] > target) {
r = mid;
}
else {
l = mid + 1;
}
}
return l;
}
};
class Solution {
public int countTarget(int[] scores, int target) {
if (scores == null || scores.length == 0) {
return 0;
}
int l = l(scores, target);
int r = r(scores, target);
if (l == -1 || r == -1) {
return 0;
}
return r - l + 1;
}
public int l(int[] nums, int target) {
int l = 0;
int r = nums.length - 1;
int m = 0;
int ans = -1;
while (l <= r) {
m = l + (r - l) / 2;
if (target <= nums[m]) {
ans = m;
r = m - 1;
} else {
l = m + 1;
}
}
if (ans != -1 && nums[ans] != target)
ans = -1;
return ans;
}
public int r(int[] nums, int target) {
int l = 0;
int r = nums.length - 1;
int m = 0;
int ans = -1;
while (l <= r) {
m = l + (r - l) / 2;
if (target >= nums[m]) {
ans = m;
l = m + 1;
} else {
r = m - 1;
}
}
if (ans != -1 && nums[ans] != target)
ans = -1;
return ans;
}
}
class Solution {
public int countTarget(int[] scores, int target) {
int l = 0;
int r = scores.length - 1;
int small = -1;
while (l <= r) {
int mid = l + (r - l) / 2;
if (scores[mid] < target) {
small = mid;
l = mid + 1;
} else {
r = mid - 1;
}
}
l = 0;
r = scores.length - 1;
int big = scores.length;
while (l <= r) {
int mid = l + (r - l) / 2;
if (scores[mid] > target) {
big = mid;
r = mid - 1;
} else {
l = mid + 1;
}
}
return big - small - 1;
}
}
思路:找第一个target和最后一个target的下标,做差+1,或者找到一头然后遍历进行统计直到不相等为止。
class Solution {
public int countTarget(int[] scores, int target) {
if(scores.length==0||scores[0]>target||scores[scores.length-1]<target) return 0;
int left=searchRangeFirst(scores,target);
if(scores[left]!=target) return 0;
int right=searchRangeLast(scores,target);
if(scores[right]!=target) right=right-1;
return right-left+1;
}
//当查找第一个大于等于target的元素的位置时,此时target为第一个红色的位置,返回right
public int searchRangeFirst(int[] nums, int target){
int left=-1;
int right=nums.length;
int mid=0;
while(left+1!=right){
mid=((right-left)/2)+left; //防止越界
if(nums[mid]<target) left=mid;
else right=mid; //合并了大于或等于两种情况。
}
return right;
}
//当查找最后一个等于target的元素的位置时,此时target为最后一个蓝色的位置,返回left
public int searchRangeLast(int[] nums, int target){
int left=-1;
int right=nums.length;
int mid=0;
while(left+1!=right){
mid=((right-left)/2)+left; //防止越界
if(nums[mid]<=target) left=mid;//合并了小于或等于两种情况。
else right=mid;
}
return left;
}
}
时间复杂度:O(logn)
空间复杂度:O(1)
class Solution {
public int[] searchRange(int[] nums, int target) {
if(nums.length 0) return new int[]{-1, -1};
int l = left_bound(nums, target);
int r = right_bound(nums, target);
if(nums[l] != target){
return new int[]{-1, -1};
}
return new int[]{l, r};
}
// 找左,判断右
int left_bound(int[] nums, int target){
int l = 0, r = nums.length-1;
while(l < r){
int m = (l + r) / 2;
if(nums[m] >= target){
r = m;
}else{
l = m + 1;
}
}
return r;
}
// 找右,判断左
int right_bound(int[] nums, int target){
int l = 0, r = nums.length-1;
while(l < r){
int m = (l + r + 1) / 2;
if(nums[m] <= target){
l = m;
}else{
r = m - 1;
}
}
return r;
}
共以下 14 个回答
打卡
解题思路
– 找出目标数字在数组中第一次出现时的firstIndex,在数组中最后一次出现时的finalIndex,出现次数=finalIndex-firstIndex+1
– 第一次出现时的firstIndex=index(最后一个<目标值 )+1
– 后一次出现时的finalIndex=index(第一个>目标值)-1
– 特别注意在外层需要判断边界值,数组为null,数组长度为0,target<数组的最小值,target>数组的最大值
【题解1】
思路: 分别找到 target 和 target+1 的左侧
思路:找左边界和找右边界,搜查两次,根据左右边界下标来计算
时间复杂度O(logn),空间复杂度O(1)
二分查找,第一个等于target和最后一个等于target
Ologn o1
先寻找第一个小于target的下标l,在寻找第一个大于target的下表r,结果为r-l-1。
时间复杂度O(logN),空间复杂度O(1)。
先找最后一个小于等于target的,再找第一个大于等于target的
先找最后一个小于目标值的数的下标,再找第一个大于目标值的数的下标,相减即为目标值的个数
//找第一个target和最后一个target的下标,然后计算个数
public int countTarget(int[] scores, int target) {
if(scores.length 0) return 0;
class Solution {
public int[] searchRange(int[] nums, int target) {
if(nums.length 0) return new int[]{-1, -1};
int l = left_bound(nums, target);
int r = right_bound(nums, target);
if(nums[l] != target){
return new int[]{-1, -1};
}
return new int[]{l, r};
}
}
时间:O(lgn)
空间:O(1)
思路:二分查找找到
target的左右边界,计算该区间的大小即可。时间复杂度:O(logn)
空间复杂度:O(1)