'''
思路:
基于二分查找的四个变形找出第一个的目标值和最后一个的目标值
需要注意的是最只有一个元素的数组的处理
'''
def search(nums, target):
r = floor_upper(nums,target)
# print("r",r)
l = floor_lower(nums,target)
# print("l",l)
if r < 0 or l < 0:
return 0
else:
return r - l + 1
def floor_lower(arr, target):
l = 0
r = len(arr) - 1
if arr[l] > target:
return -1
if r == l and arr[l] == target:
return 0
if arr[l] == target:
return l
while l < r:
#向上圆整
mid = l + (r - l + 1) // 2
if arr[mid] > target:
r = mid - 1
elif arr[mid] == target:
r = mid - 1
else:
l = mid
if l + 1 < len(arr) and arr[l + 1] == target:
return l + 1
return -1
class Solution {
public int search(int[] nums, int target) {
if (nums.length == 0) return 0;
int l = 0, r = nums.length - 1;
while (l < r) {
int mid = l + r >> 1;
if (nums[mid] < target) l = mid + 1;
else r = mid;
}
if (nums[l] != target) return 0;
int ll = l;
l = 0; r = nums.length - 1;
while (l < r) {
int mid = l + r + 1 >> 1;
if (nums[mid] > target) r = mid - 1;
else l = mid;
}
return l - ll + 1;
}
}
func search(nums []int, target int) int {
left := search1(nums, target)
right := search2(nums, target)
if left < 0 || right < 0 {
return 0
}
return right - left + 1
}
//二分查找第一个等于tar的下标
func search1(nums []int, tar int) int {
if nums == nil || len(nums) == 0 {
return -1
}
l := 0
r := len(nums) - 1
for l < r {
mid := l + (r - l) / 2
if nums[mid] >= tar {
r = mid
}else{
l = mid + 1
}
}
if nums[l] != tar {
return -1
}
return l
}
//二分查找最后一个等于tar的下标
func search2(nums []int, tar int) int {
if nums == nil || len(nums) == 0 {
return -1
}
l := 0
r := len(nums) - 1
for l < r {
mid := l + (r - l + 1) / 2
if nums[mid] <= tar {
l = mid
}else{
r = mid - 1
}
}
if nums[l] != tar {
return -1
}
return l
}
class Solution:
def search(self, nums: List[int], target: int) -> int:
def helper(tar): # 查找右边界的通用函数,应该记住
i, j = 0, len(nums) - 1
while i <= j:
m = (i + j) // 2
if nums[m] <= tar: i = m + 1
else: j = m - 1
return i
return helper(target) - helper(target - 1)
class Solution {
public int search(int[] nums, int target) {
if (nums.length == 0)
return 0;
int l = 0, r = nums.length - 1, res = 0;
while (l <= r) {
int mid = l + (r - l) / 2;
if (nums[mid] == target) {
l = mid;
res++;
break;
} else if (nums[mid] < target)
l = mid + 1;
else
r = mid - 1;
}
int t = l;
while (++l <= r) {
if (nums[l] == target)
res++;
else
break;
}
while (--t >= 0) {
if (nums[t] == target)
res++;
else
break;
}
return res;
}
public static void main(String[] args) {
int[] ary = {1};
Solution s = new Solution();
int search = s.search(ary, 1);
System.out.println(search);
}
}
class Solution {
public int search(int[] nums, int target) {
//方法一 循环遍历
int count = 0;
for (int i = 0; i < nums.length; i++) {
if (target == nums[i]){
count++;
}
}
return count;
//方法二 二分查找 时间复杂度O(logn) 空间复杂度O(1)
int left = 0, right = nums.length - 1;
int L = 0 , R = 0;
while(left <= right){
int mid = left + ((right - left) >> 1);
if(nums[mid] <= target){
left = mid + 1;
}else{
right = mid - 1;
}
}
R = left ; //找到左边界
if(right > 0 && nums[right] != target){
return 0;
}
left = 0; right = nums.length - 1;
while(left <= right){
int mid = left + ((right - left) >> 1);
if(nums[mid] < target){
left = mid + 1;
}else{
right = mid - 1;
}
}
L = right;
return R - L - 1;
}
}
class Solution {
public int search(int[] nums, int target) {
int left = leftBound(nums,target);
int right = rightBound(nums,target);
return left == -1 ? 0 : right - left + 1;
}
int leftBound(int[] nums, int target){
int left = 0;
int right = nums.length - 1;
while(left <= right){
int mid = left + (right - left) / 2;
if(nums[mid] > target){
right = mid - 1;
}else if(nums[mid] < target){
left = mid + 1;
}else if(nums[mid] == target){
right = mid - 1;
}
}
if(left == nums.length){
return -1;
}
return nums[left] == target ? left : -1;
}
int rightBound(int[] nums, int target){
int left = 0;
int right = nums.length - 1;
while(left <= right){
int mid = left + (right - left) / 2;
if(nums[mid] > target){
right = mid - 1;
}else if(nums[mid] < target){
left = mid + 1;
}else if(nums[mid] == target){
left = mid + 1;
}
}
if(right < 0){
return -1;
}
return nums[right] == target ? right : -1;
}
}
//查找右边界
class Solution {
public:
int helper(vector& nums,int tar){
int l=0,r=nums.size()-1;
while(l<=r){
int mid=l+(r-l)/2;
if(nums[mid]<=tar) l=mid+1;
else r=mid-1;
}
return l;
}
int search(vector& nums, int target) {
int l=helper(nums,target-1);
int r=helper(nums,target);
return r-l;
class Solution {
public int search(int[] nums, int target) {
return Find(nums, target) - Find(nums, target - 1);
}
int Find(int[] nums, int tar) {
int i = 0, j = nums.length - 1;
while(i <= j) {
int m = (i + j) / 2;
if(nums[m] <= tar) i = m + 1;
else j = m - 1;
}
return i;
}
}
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
int count = 0;
while (left <= right) {
int mid = (right - left) / 2 + left;
if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid - 1;
} else {
for (int i = left; i <= right; i++) {
if (nums[i] == target) {
count++;
}
}
return count;
}
}
return count;
}
}
class Solution {
public int search(int[] nums, int target) {
int left = 0, right=nums.length-1;
int count = 0;
while(left<right){
int mid = (right-left)/2+left;
if(nums[mid]>=target) right=mid;
else left = mid+1;
}
while(left<nums.length&&nums[left++]==target){
count++;
}
return count;
}
}
class Solution {
public:
int biarySearch(vector<int> &nums, int target, bool lower){
int left = 0, right = nums.size() - 1, ans = nums.size();
while(left <= right){
int mid = (left + right)/2;
if(nums[mid] > target || (lower && nums[mid] >= target)){
right = mid - 1;
ans = mid;
}else left = mid + 1;
}
return ans;
}
int search(vector<int>& nums, int target) {
int left = biarySearch(nums, target, true);
int right = biarySearch(nums, target, false);
return right - left;
}
};
class Solution {
public int search(int[] nums, int target) {
int res1 = floor_lower(nums,target);
int res2 = floor_upper(nums,target);
if(res1 != -1){
return res2-res1+1;
}
return 0;
}
int floor_upper(int[] arr, int target) {
int len = arr.length;
int r = len - 1;
int l = 0;
while (l <= r) {
int mid = (l + r) / 2;
if (arr[mid] > target) {
r = mid - 1;
} else {
l = mid + 1;
}
}
if(l>0){
if(arr[l-1] == target){
return l-1;
}
}
return -1;
}
int floor_lower(int[] arr, int target) {
int len = arr.length;
int r = len - 1;
int l = 0;
while (l <= r) {
int mid = (l + r) / 2;
if (arr[mid] >= target) {
r = mid - 1;
} else {
l = mid + 1;
}
}
if(r<len-1){
if(arr[r + 1] == target){
return r + 1;
}
}
return -1;
}
}
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
int k = 0;
while(left < right){
//向下取整
int mid = left + (right - left)/2;
if(nums[mid] >= target){
right = mid;
}else if(nums[mid] < target){
left = mid + 1;
}
}
while(left < nums.length && nums[left] == target){
k++;
left++;
}
return k;
}
}
class Solution {
public int search(int[] nums, int target) {
int right = floor_upper(nums, target);
int left = floor_lower(nums, target);
if (right == -1) {
return 0;
}
return right - left + 1;
}
public int floor_upper(int[] arr, int target) {
int left = 0;
int right = arr.length - 1;
while (left <= right) {
int mid = (right - left) / 2 + left;
if (arr[mid] > target) {
right = mid - 1;
} else {
left = mid + 1;
}
}
if (left > 0) {
if (arr[left - 1] == target) {
return left - 1;
}
}
return (left < arr.length && arr[left] == target) ? left : -1;
}
public int floor_lower(int[] arr, int target) {
int left = 0;
int right = arr.length - 1;
while (left <= right) {
int mid = (right - left) / 2 + left;
if (arr[mid] >= target) {
right = mid - 1;
} else {
left = mid + 1;
}
}
if (right < arr.length - 1) {
if (arr[right + 1] == target) {
return right + 1;
}
}
return (right >= 0 && arr[right] == target) ? right : -1;
}
}
class Solution {
public int search(int[] nums, int target) {
int left = Binary_Search(nums,target);
if(left == -1) return 0;
int right;
for(right = left + 1;right < nums.length && nums[right] == nums[left];right++);
return right - left;
}
//搜索当前数组的左边界
public int Binary_Search(int[] nums,int target){
int left = 0;
int right = nums.length;
while(left < right){
int mid = left + (right - left) / 2;
if(nums[mid] == target){
right = mid;
}else if(nums[mid] > target){
right = mid;
}else if(nums[mid] < target){
left = mid + 1;
}
}
if(left == nums.length) return -1;
return nums[left] == target ? left : -1;
}
}
class Solution:
def search(self, nums: List[int], target: int) -> int:
def helper(tar):
i, j = 0, len(nums) - 1
while i <= j:
m = (i + j) // 2
if nums[m] > tar:
j = m -1
else:
i = m + 1
return i
return helper(target) - helper(target - 1)
共以下 36 个回答
时间O(logn) 空间O(1)
解题思路:使用二分查找分别找出第一个等于target和最后一个等于target的元素,两个相减再加1即为结果
时间复杂度:O(logN)
空间复杂度:O(1)
时间复杂度O(logn)
好思路👍🏻
二分,实际上是寻找大于target的最小数和小于target的最大数
时间复杂度:O(lgN)
空间复杂度:O(1)
思路:找到target的左右边界,来计算出个数。时间复杂度为O(logN),空间复杂度O(1)。
思路:找到第一个等于 target 的索引,然后从这个索引开始,分别向左和向右遍历,一旦不等于就终止
时间复杂度 O(logN)
**空间复杂度 O(1) **
分别找到左右边界,最后进行运算得出元素个数。时间O(logn),空间O(1)
//查找右边界& nums,int tar){ & nums, int target) {
class Solution {
public:
int helper(vector
int l=0,r=nums.size()-1;
while(l<=r){
int mid=l+(r-l)/2;
if(nums[mid]<=tar) l=mid+1;
else r=mid-1;
}
return l;
}
int search(vector
int l=helper(nums,target-1);
int r=helper(nums,target);
return r-l;
};
先找到出现第一次的下标,再找最后一次出现的下标,然后做差
先寻找左边界
我写的要比这个麻烦许多,leetcode给出的最优题解
时间复杂度O(logn)
空间复杂度O(1)
很垃圾
先找到target-1的右边界,然后找到target的右边界,target-1的右边界就是target的左边界
先找到最左边的target,再往后找相同的
使用二分查找法寻找数组中target值的重复情况
前天的模板直接用了
时间O(log(n))
空间O(1)
时间复杂度O(lgn),空间复杂度O(1)
时间:O(log(n)),空间:O(1)
先查出左区间,再从左往右找
时间复杂度O(logn)
找出左右边界
时间复杂度 O(logn)