class Solution {
public:
int upper(vector<int>& nums, int target){
// if not exist, return -1
int len = nums.size();
if (nums[len - 1] < target) return -1;
int l = 0, r = len - 1;
while (l < r) {
int mid = (r - l) / 2 + l;
// printf("l = %d, m = %d, r = %d\n", l, mid, r);
if (nums[mid] <= target) l = mid + 1;
else r = mid - 1;
}
if (nums[l] != target) {
if (l && nums[l - 1] == target) return l - 1;
else return -1;
}
return l;
}
int lower(vector<int>& nums, int target){
// if not exist, return -1
int len = nums.size();
if (nums[0] > target) return -1;
int l = 0, r = len - 1;
while (l < r) {
int mid = (r - l) / 2 + l;
// printf("l = %d, m = %d, r = %d\n", l, mid, r);
if (nums[mid] >= target) r = mid - 1;
else { // nums[mid] < target
if (l != mid) l = mid;
else if (nums[r] <= target) l = r;
else return l;
}
}
if (nums[l] != target) {
if (l < len - 1 && nums[l + 1] == target) return l + 1;
else return -1;
}
return l;
}
int search(vector<int>& nums, int target) {
if (nums.empty()) return 0;
int up = upper(nums, target);
int low = lower(nums, target);
// printf("up = %d, low = %d\n", up, low);
if (up == -1) return 0;
return (up - low + 1);
}
};
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length-1;
if(nums==null||nums.length<=0||nums[left]>target||nums[right]<target){
return 0;
}
while(left<right){
int mid=(right-left+1)/2+left;
if(nums[mid]>target){
right=mid-1;
}else if(nums[mid]==target){
right=mid-1;
}else{
left=mid;
}
}
int ans=0;
if(nums[left]==target){
while(left<nums.length&&nums[left++]==target)ans++;
}else{
if(left+1<nums.length&&nums[left+1]==target)left++;
}
while(left<nums.length&&nums[left++]==target)ans++;
return ans;
}
}
class Solution:
def search(self, nums: List[int], target: int) -> int:
if not nums:
return 0
left = self.upper(nums, target)
right = self.lower(nums, target)
if left == -1 or right == -1:
return 0
return right - left + 1
def upper(self, nums, target):
left = 0
right = len(nums) - 1
if nums[right] < target:
return -1
while left < right:
mid = (right - left) // 2 + left
if nums[mid] == target:
right = mid
elif nums[mid] < target:
left = mid + 1
else:
right = mid
return left
def lower(self, nums, target):
left = 0
right = len(nums) - 1
if nums[left] > target:
return -1
while left < right:
mid = (right - left + 1) // 2 + left
if nums[mid] == target:
left = mid
elif nums[mid] < target:
left = mid
else:
right = mid - 1
return left
class Solution {
public int search(int[] nums, int target) {
int greate = firstGreater(nums,target);
int less = lastLess(nums,target);
if(greate>=0 && less>=0){
return greate-less+1;
}
return 0;
}
public static int firstGreater(int[] arr,int target){
int left = 0;
int right = arr.length - 1;
if (right<0|| arr[right] < target) {
return -1;
}
while (left < right) {
//注意向上取余
int mid = (right - left+1) / 2 + left;
if (arr[mid] > target) {
right = mid-1;
} else if (arr[mid] < target) {
left = mid + 1;
} else if (arr[mid] == target) {
left = mid;
}
}
if (arr[left] == target) {
return left;
}
return -1;
}
public static int lastLess(int[] arr,int target){
int left = 0;
int right = arr.length - 1;
if (right<0 || arr[left] > target) {
return -1;
}
while (left < right) {
int mid = (right-left) / 2 +left;
if (arr[mid] > target) {
right = mid;
} else if (arr[mid] < target) {
left = mid+1;
} else if (arr[mid] == target) {
right = mid ;
}
}
if (arr[left] == target) {
return left;
}
return -1;
}
}
public int search(int[] nums, int target) {
int bound = leftBound(nums,target);
if(bound == -1) return 0;
int res = 0;
for(int i = bound; i < nums.length; i++){
if(nums[i] == target) res++;
else if(nums[i] > target) break;
}
return res;
}
public int leftBound(int[] num, int target){
int l = 0, r = num.length-1;
int bound = -1;
while(l <= r){
int mid = l + (r - l)/2;
if(num[mid] > target){
r = mid-1;
}else if(num[mid] < target){
l = mid + 1;
}else{
bound = mid;
r = mid-1;
}
}
return bound;
}
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
def floor_upper_bs(t):
l, r = 0, len(nums) - 1
if (nums[r] < t):
return -1
elif nums[r] == t:
return r
while l < r:
m = (r - l) // 2 + l
if (nums[m] > t):
r = m
else:
l = m + 1
if (l - 1 >= 0 and nums[l - 1] == t):
return l - 1
return l
if not nums:
return [-1, -1]
left = floor_upper_bs(target - 1)
if nums[left] != target:
left = left + 1 if (left + 1 <= len(nums) - 1 and nums[left + 1] == target) else -1
right = floor_upper_bs(target)
print(right, nums[right])
right = right if nums[right] == target else -1
return [left, right]
class Solution {
public int search(int[] nums, int target) {
int left=0;
int right=nums.length-1;
while(left<=right){
int mid=(left+right)/2;
if(target<nums[mid])
right=mid-1;
else
left=mid+1;
}
int j=left;
if(right>=0&&nums[right]!=target)
return 0;
left=0;
right=nums.length-1;
while(left<=right){
int mid=(left+right)/2;
if(target>nums[mid])
left=mid+1;
else
right=mid-1;
}
int i=left;
return j-i;
}
}
c++实现
int search(vector& nums, int target) {
if(nums.empty()) return 0;
int l = 0, r = nums.size() - 1; //二分范围
while( l < r) //查找元素的开始位置
{
int mid = (l + r )/2;
if(nums[mid] >= target) r = mid;
else l = mid + 1;
}
if( nums[r] != target) return 0; //查找失败
int begin = r;
l = 0, r = nums.size() - 1; //二分范围
while( l < r) //查找元素的结束位置
{
int mid = (l + r + 1)/2;
if(nums[mid] <= target ) l = mid;
else r = mid - 1;
}
int end = r;
return end - begin + 1;
}
class Solution{
public:
int search(vector<int>& nums, int target){
// 寻找第一个大于等于target的数的下标
auto search1 = [&](vector<int>& nums, int target) -> int{
if(nums.empty()){
return -1;
}
int left = 0, right = nums.size()-1;
while(left<right){
int mid = left + (right - left) / 2;
if(nums[mid] < target){
left = mid+1;
}else{
right = mid;
}
}
return left;
};
// 寻找最后一个大于等于 target的数的下标
auto search = [&](vector<int>& nums, int target) -> int{
if(nums.empty()){
return -1;
}
int left = 0, right = nums.size() - 1;
while(left<right){
int mid = left + (right - left + 1)/2;
if(nums[mid] > target){
right = mid - 1;
}else{
left = mid;
}
}
return left;
};
int left = search1(nums,target);
int right = search2(nums,target);
if(left == -1 || right == -1 || nums[left] != target || nums[right] != target){
return 0;
}
return right - left +1 ;
}
}
class Solution {
public int search(int[] nums, int target) {
if(nums == null || nums.length == 0){
return 0;
}
int left = getLeft(nums, target);
int right = getRight(nums, target);
return left == -1 || right == -1 ? 0 : right - left + 1;
}
// 寻找第一个等于target数的下标
public int getLeft(int[] nums, int target){
int l = 0, r = nums.length - 1;
while (l < r) {
int mid = l + ((r - l) >> 1);
if(nums[mid] > target){
r = mid;
} else if (nums[mid] == target){
r = mid;
} else {
l = mid + 1;
}
}
return nums[l] == target ? l : -1;
}
// 寻找最后一个等于target的下标
public int getRight(int[] nums, int target){
int l = 0, r = nums.length - 1;
while(l < r){
int mid = l + ((r - l + 1) >> 1);
if(nums[mid] > target){
r = mid - 1;
} else if (nums[mid] == target) {
l = mid;
} else {
l = mid;
}
}
return nums[l] == target ? l : -1;
}
}
共以下 29 个回答
“`java
//第一个大于target的下标
class Solution {
public int countTarget(int[] scores, int target) {
if (scores == null || scores.length == 0) {
return 0;
}
int l = 0;
int r = scores.length – 1;
if (scores[r] < target) { return 0; } while (l < r) { int mid = (r + l)/2; if (scores[mid] > target) {
r = mid;
} else {
l = mid + 1;
}
}
int count = 0;
for (int j = l; j >= 0; j–) {
if (scores[j] < target) { break; } else if (scores[j] == target) { count++; } } return count; } }
class Solution {
public int search(int[] nums, int target) {
int l=0,r=nums.length-1;
}
加油
“`javatarget){=0&&nums[l-1]==target){
自己写的,刚好是帅地说的第一种
class Solution {
//时间复杂度可能会蜕变为O(n)
public int search(int[] nums, int target) {
//使用二分法找到其,然后再增加
//1.先处理特殊情况
if(nums.length==0) return 0;
if(nums[0]>target||nums[nums.length-1]
r=middle-1;
}else if(nums[middle]
count++;
l–;
}
return count;
}
}
“`C++& nums, int target) {
int search(vector
int count = 0;
int left = 0;
int right = nums.size() – 1;
}
}
“`
实现了一个在有序数组中查找目标值的函数。
首先,定义了一个Solution类,其中包含了两个函数leftBound和rightBound,分别用于查找目标值的左边界和右边界。
在search函数中,首先判断数组是否为空,如果为空则直接返回0。
然后调用leftBound和rightBound函数分别找到目标值的左边界和右边界,并计算区间的长度。
如果右边界为-1,则表示目标值不存在,返回0;否则返回右边界减去左边界再加1的结果。
【思路】讲问题解构为“找到该元素的第一个下标”与“找到该元素的最后一个下标”
【复杂度】时间O(logn),空间O(1)
【优化】还有优化的空间,可以把查找过程合并
看完模板后按着自己理解来的,可能有点繁琐
最坏情况下时间复杂度达到了O(n)
通过数组元素等于target时,让左右边界等于mid控制找到数组中第一个或最后一个target元素。
复杂度
时间复杂度: $O(nlogn)$
空间复杂度: $O(1)$
Code
先用二分查找找到等于target的左边界,再向右遍历计算个数。
思路:使用二分查找模板,寻找target的两侧边界left与right,若存在则返回right-left+1即为出现次数,否则返回0
时间复杂度O(logn) 空间复杂度O(1)
返回了范围
二分查找
时间复杂度O(logn)
c++实现& nums, int target) {
int search(vector
if(nums.empty()) return 0;
时间复杂度O(logn) 空间复杂度O(1)
时间复杂度:log(n)
空间复杂度:O(1)
时间复杂度:O(logN)
空间复杂度:O(1)
寻找第一个等于target的数,考虑往右边寻找,第一个就是了
寻找最后一个等于target的数,考虑往左边寻找,第一个就是了
结合帅地给的四个模板
时间:O(logn)
空间:O(1)
MY